Skip to content

Commit

Permalink
fix #168: integrated logging story
Browse files Browse the repository at this point in the history
  • Loading branch information
tjanczuk committed May 23, 2012
1 parent 96fb80f commit 7427f22
Show file tree
Hide file tree
Showing 27 changed files with 775 additions and 445 deletions.
7 changes: 4 additions & 3 deletions src/config/iisnode_schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Details at http://learn.iis.net/page.aspx/241/configuration-extensibility/
<attribute name="asyncCompletionThreadCount" type="uint" defaultValue="0"/>
<attribute name="nodeProcessCountPerApplication" type="uint" defaultValue="1"/>
<attribute name="nodeProcessCommandLine" type="string" expanded="true" defaultValue="&quot;%programfiles%\nodejs\node.exe&quot;"/>
<attribute name="interceptor" type="string" expanded="true" defaultValue="&quot;%programfiles%\iisnode\interceptor.js&quot;" />
<attribute name="maxConcurrentRequestsPerProcess" type="uint" allowInfitnite="true" defaultValue="1024"/>
<attribute name="maxNamedPipeConnectionRetry" type="uint" defaultValue="24"/>
<attribute name="namedPipeConnectionRetryDelay" type="uint" defaultValue="250"/>
Expand All @@ -40,14 +41,14 @@ Details at http://learn.iis.net/page.aspx/241/configuration-extensibility/
<attribute name="maxRequestBufferSize" type="uint" defaultValue="65536"/>
<attribute name="uncFileChangesPollingInterval" type="uint" defaultValue="5000"/>
<attribute name="gracefulShutdownTimeout" type="uint" defaultValue="60000"/>
<attribute name="logDirectoryNameSuffix" type="string" expanded="true" defaultValue="logs"/>
<attribute name="logDirectory" type="string" expanded="true" defaultValue="iisnode"/>
<attribute name="debuggingEnabled" type="bool" defaultValue="true"/>
<attribute name="debuggerPathSegment" type="string" expanded="true" defaultValue="debug"/>
<attribute name="debuggerPortRange" type="string" expanded="true" defaultValue="5058-6058"/>
<attribute name="logFileFlushInterval" type="uint" defaultValue="5000"/>
<attribute name="maxLogFileSizeInKB" type="uint" defaultValue="128"/>
<attribute name="maxTotalLogFileSizeInKB" type="uint" defaultValue="1024"/>
<attribute name="maxLogFiles" type="uint" defaultValue="20"/>
<attribute name="loggingEnabled" type="bool" defaultValue="true"/>
<attribute name="appendToExistingLog" type="bool" defaultValue="false"/>
<attribute name="devErrorsEnabled" type="bool" defaultValue="true"/>
<attribute name="flushResponse" type="bool" defaultValue="false"/>
<attribute name="watchedFiles" type="string" expanded="true" defaultValue="*.js;iisnode.yml"/>
Expand Down
7 changes: 4 additions & 3 deletions src/config/iisnode_schema_x64.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Details at http://learn.iis.net/page.aspx/241/configuration-extensibility/
<attribute name="asyncCompletionThreadCount" type="uint" defaultValue="0"/>
<attribute name="nodeProcessCountPerApplication" type="uint" defaultValue="1"/>
<attribute name="nodeProcessCommandLine" type="string" expanded="true" defaultValue="&quot;%programfiles(x86)%\nodejs\node.exe&quot;"/>
<attribute name="interceptor" type="string" expanded="true" defaultValue="&quot;%programfiles%\iisnode\interceptor.js&quot;" />
<attribute name="maxConcurrentRequestsPerProcess" type="uint" allowInfitnite="true" defaultValue="1024"/>
<attribute name="maxNamedPipeConnectionRetry" type="uint" defaultValue="24"/>
<attribute name="namedPipeConnectionRetryDelay" type="uint" defaultValue="250"/>
Expand All @@ -40,14 +41,14 @@ Details at http://learn.iis.net/page.aspx/241/configuration-extensibility/
<attribute name="maxRequestBufferSize" type="uint" defaultValue="65536"/>
<attribute name="uncFileChangesPollingInterval" type="uint" defaultValue="5000"/>
<attribute name="gracefulShutdownTimeout" type="uint" defaultValue="60000"/>
<attribute name="logDirectoryNameSuffix" type="string" expanded="true" defaultValue="logs"/>
<attribute name="logDirectory" type="string" expanded="true" defaultValue="iisnode"/>
<attribute name="debuggingEnabled" type="bool" defaultValue="true"/>
<attribute name="debuggerPathSegment" type="string" expanded="true" defaultValue="debug"/>
<attribute name="debuggerPortRange" type="string" expanded="true" defaultValue="5058-6058"/>
<attribute name="logFileFlushInterval" type="uint" defaultValue="5000"/>
<attribute name="maxLogFileSizeInKB" type="uint" defaultValue="128"/>
<attribute name="maxTotalLogFileSizeInKB" type="uint" defaultValue="1024"/>
<attribute name="maxLogFiles" type="uint" defaultValue="20"/>
<attribute name="loggingEnabled" type="bool" defaultValue="true"/>
<attribute name="appendToExistingLog" type="bool" defaultValue="false"/>
<attribute name="devErrorsEnabled" type="bool" defaultValue="true"/>
<attribute name="flushResponse" type="bool" defaultValue="false"/>
<attribute name="watchedFiles" type="string" expanded="true" defaultValue="*.js;iisnode.yml"/>
Expand Down
59 changes: 59 additions & 0 deletions src/config/iisnode_schema_x64_wow.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!--
This file describes the configuration schema for the iisnode IIS module.
To install this schema:
1. This file must be saved to %windir%\system32\inetsrv\config\schema.
2. The following entry must be added to %windir%\system32\inetsrv\config\applicationhost.config:
<configSections>
...
<sectionGroup name="system.webServer">
<section name="iisnode" overrideModeDefault="Allow"/>
...
</sectionGroup>
</configSections>
Following installation, the iisnode module can be configured using the web.config file specific to the application:
<system.webServer>
<iisnode ... />
</system.webServer>
Details at http://learn.iis.net/page.aspx/241/configuration-extensibility/
-->

<configSchema>
<sectionSchema name="system.webServer/iisnode">
<attribute name="node_env" type="string" expanded="true" defaultValue="%node_env%"/>
<attribute name="asyncCompletionThreadCount" type="uint" defaultValue="0"/>
<attribute name="nodeProcessCountPerApplication" type="uint" defaultValue="1"/>
<attribute name="nodeProcessCommandLine" type="string" expanded="true" defaultValue="&quot;%programfiles(x86)%\nodejs\node.exe&quot;"/>
<attribute name="interceptor" type="string" expanded="true" defaultValue="&quot;%programfiles(x86)%\iisnode\interceptor.js&quot;" />
<attribute name="maxConcurrentRequestsPerProcess" type="uint" allowInfitnite="true" defaultValue="1024"/>
<attribute name="maxNamedPipeConnectionRetry" type="uint" defaultValue="24"/>
<attribute name="namedPipeConnectionRetryDelay" type="uint" defaultValue="250"/>
<attribute name="maxNamedPipeConnectionPoolSize" type="uint" defaultValue="512"/>
<attribute name="maxNamedPipePooledConnectionAge" type="uint" defaultValue="30000"/>
<attribute name="initialRequestBufferSize" type="uint" defaultValue="4096"/>
<attribute name="maxRequestBufferSize" type="uint" defaultValue="65536"/>
<attribute name="uncFileChangesPollingInterval" type="uint" defaultValue="5000"/>
<attribute name="gracefulShutdownTimeout" type="uint" defaultValue="60000"/>
<attribute name="logDirectory" type="string" expanded="true" defaultValue="iisnode"/>
<attribute name="debuggingEnabled" type="bool" defaultValue="true"/>
<attribute name="debuggerPathSegment" type="string" expanded="true" defaultValue="debug"/>
<attribute name="debuggerPortRange" type="string" expanded="true" defaultValue="5058-6058"/>
<attribute name="maxLogFileSizeInKB" type="uint" defaultValue="128"/>
<attribute name="maxTotalLogFileSizeInKB" type="uint" defaultValue="1024"/>
<attribute name="maxLogFiles" type="uint" defaultValue="20"/>
<attribute name="loggingEnabled" type="bool" defaultValue="true"/>
<attribute name="devErrorsEnabled" type="bool" defaultValue="true"/>
<attribute name="flushResponse" type="bool" defaultValue="false"/>
<attribute name="watchedFiles" type="string" expanded="true" defaultValue="*.js;iisnode.yml"/>
<attribute name="enableXFF" type="bool" defaultValue="false"/>
<attribute name="promoteServerVars" type="string" defaultValue=""/>
<attribute name="configOverrides" type="string" expanded="true" defaultValue="iisnode.yml"/>
</sectionSchema>
</configSchema>
125 changes: 101 additions & 24 deletions src/iisnode/cmoduleconfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ HTTP_MODULE_ID CModuleConfiguration::moduleId = NULL;
BOOL CModuleConfiguration::invalid = FALSE;

CModuleConfiguration::CModuleConfiguration()
: nodeProcessCommandLine(NULL), logDirectoryNameSuffix(NULL), debuggerPathSegment(NULL),
: nodeProcessCommandLine(NULL), logDirectory(NULL), debuggerPathSegment(NULL),
debugPortRange(NULL), debugPortStart(0), debugPortEnd(0), node_env(NULL), watchedFiles(NULL),
enableXFF(FALSE), promoteServerVars(NULL), promoteServerVarsRaw(NULL), configOverridesFileName(NULL),
configOverrides(NULL)
configOverrides(NULL), interceptor(NULL)
{
InitializeSRWLock(&this->srwlock);
}
Expand All @@ -23,10 +23,15 @@ CModuleConfiguration::~CModuleConfiguration()
this->nodeProcessCommandLine = NULL;
}

if (NULL != this->logDirectoryNameSuffix)
if (NULL != this->interceptor) {
delete [] this->interceptor;
this->interceptor = NULL;
}

if (NULL != this->logDirectory)
{
delete [] this->logDirectoryNameSuffix;
this->logDirectoryNameSuffix = NULL;
delete [] this->logDirectory;
this->logDirectory = NULL;
}

if (NULL != this->debuggerPathSegment)
Expand Down Expand Up @@ -240,6 +245,48 @@ HRESULT CModuleConfiguration::CreateNodeEnvironment(IHttpContext* ctx, DWORD deb
tmpIndex += propertySize + 1;
}

if (CModuleConfiguration::GetLoggingEnabled(ctx))
{
// set IISNODE_LOGGINGENABLED variable

ErrorIf((tmpSize - (tmpIndex - tmpStart)) < 25, ERROR_NOT_ENOUGH_MEMORY);
sprintf(tmpIndex, "IISNODE_LOGGINGENABLED=1");
tmpIndex += 25;

// set IISNODE_LOGDIRECTORY variable based on the iisnode/@logDirectory configuration setting, if not empty

LPWSTR logDirectory = CModuleConfiguration::GetLogDirectory(ctx);
if (0 != wcscmp(L"", logDirectory))
{
ErrorIf((tmpSize - (tmpIndex - tmpStart)) < 22, ERROR_NOT_ENOUGH_MEMORY);
sprintf(tmpIndex, "IISNODE_LOGDIRECTORY=");
tmpIndex += 21;
ErrorIf(0 == (propertySize = WideCharToMultiByte(CP_ACP, 0, logDirectory, wcslen(logDirectory), NULL, 0, NULL, NULL)), E_FAIL);
ErrorIf((propertySize + 1) > (tmpSize - (tmpStart - tmpIndex)), ERROR_NOT_ENOUGH_MEMORY);
ErrorIf(propertySize != WideCharToMultiByte(CP_ACP, 0, logDirectory, wcslen(logDirectory), tmpIndex, propertySize, NULL, NULL), E_FAIL);
tmpIndex += propertySize + 1;
}

// set IISNODE_MAXTOTALLOGFILESIZEINKB, IISNODE_MAXLOGFILESIZEINKB, and IISNODE_MAXLOGFILES variables

char tmp[64];
sprintf(tmp, "%d", CModuleConfiguration::GetMaxTotalLogFileSizeInKB(ctx));
ErrorIf((tmpSize - (tmpIndex - tmpStart)) < (strlen(tmp) + 33), ERROR_NOT_ENOUGH_MEMORY);
sprintf(tmpIndex, "IISNODE_MAXTOTALLOGFILESIZEINKB=%s", tmp);
tmpIndex += strlen(tmp) + 33;

sprintf(tmp, "%d", CModuleConfiguration::GetMaxLogFileSizeInKB(ctx));
ErrorIf((tmpSize - (tmpIndex - tmpStart)) < (strlen(tmp) + 28), ERROR_NOT_ENOUGH_MEMORY);
sprintf(tmpIndex, "IISNODE_MAXLOGFILESIZEINKB=%s", tmp);
tmpIndex += strlen(tmp) + 28;

sprintf(tmp, "%d", CModuleConfiguration::GetMaxLogFiles(ctx));
ErrorIf((tmpSize - (tmpIndex - tmpStart)) < (strlen(tmp) + 21), ERROR_NOT_ENOUGH_MEMORY);
sprintf(tmpIndex, "IISNODE_MAXLOGFILES=%s", tmp);
tmpIndex += strlen(tmp) + 21;

}

// add a trailing zero to new variables

ErrorIf(1 > (tmpSize - (tmpStart - tmpIndex)), ERROR_NOT_ENOUGH_MEMORY);
Expand Down Expand Up @@ -584,21 +631,21 @@ HRESULT CModuleConfiguration::ApplyConfigOverrideKeyValue(IHttpContext* context,
{
CheckError(GetDWORD(valueStart, &config->gracefulShutdownTimeout));
}
else if (0 == strcmpi(keyStart, "logFileFlushInterval"))
else if (0 == strcmpi(keyStart, "maxTotalLogFileSizeInKB"))
{
CheckError(GetDWORD(valueStart, &config->logFileFlushInterval));
CheckError(GetDWORD(valueStart, &config->maxTotalLogFileSizeInKB));
}
else if (0 == strcmpi(keyStart, "maxLogFileSizeInKB"))
{
CheckError(GetDWORD(valueStart, &config->maxLogFileSizeInKB));
}
else if (0 == strcmpi(keyStart, "loggingEnabled"))
else if (0 == strcmpi(keyStart, "maxLogFiles"))
{
CheckError(GetBOOL(valueStart, &config->loggingEnabled));
CheckError(GetDWORD(valueStart, &config->maxLogFiles));
}
else if (0 == strcmpi(keyStart, "appendToExistingLog"))
else if (0 == strcmpi(keyStart, "loggingEnabled"))
{
CheckError(GetBOOL(valueStart, &config->appendToExistingLog));
CheckError(GetBOOL(valueStart, &config->loggingEnabled));
}
else if (0 == strcmpi(keyStart, "devErrorsEnabled"))
{
Expand All @@ -616,9 +663,9 @@ HRESULT CModuleConfiguration::ApplyConfigOverrideKeyValue(IHttpContext* context,
{
CheckError(GetBOOL(valueStart, &config->enableXFF));
}
else if (0 == strcmpi(keyStart, "logDirectoryNameSuffix"))
else if (0 == strcmpi(keyStart, "logDirectory"))
{
CheckError(GetString(valueStart, &config->logDirectoryNameSuffix));
CheckError(GetString(valueStart, &config->logDirectory));
}
else if (0 == strcmpi(keyStart, "node_env"))
{
Expand Down Expand Up @@ -659,7 +706,24 @@ HRESULT CModuleConfiguration::ApplyConfigOverrideKeyValue(IHttpContext* context,
strcpy(config->nodeProcessCommandLine, "");
}
}
else if (0 == strcmpi(keyStart, "interceptor"))
{
if (config->interceptor)
{
delete [] config->interceptor;
config->interceptor = NULL;
}

ErrorIf(NULL == (config->interceptor = new char[MAX_PATH]), ERROR_NOT_ENOUGH_MEMORY);
if (valueStart)
{
strcpy(config->interceptor, valueStart);
}
else
{
strcpy(config->interceptor, "");
}
}

return S_OK;
Error:
Expand Down Expand Up @@ -996,13 +1060,13 @@ HRESULT CModuleConfiguration::GetConfig(IHttpContext* context, CModuleConfigurat
CheckError(GetDWORD(section, L"maxRequestBufferSize", &c->maxRequestBufferSize));
CheckError(GetDWORD(section, L"uncFileChangesPollingInterval", &c->uncFileChangesPollingInterval));
CheckError(GetDWORD(section, L"gracefulShutdownTimeout", &c->gracefulShutdownTimeout));
CheckError(GetDWORD(section, L"logFileFlushInterval", &c->logFileFlushInterval));
CheckError(GetDWORD(section, L"maxTotalLogFileSizeInKB", &c->maxTotalLogFileSizeInKB));
CheckError(GetDWORD(section, L"maxLogFileSizeInKB", &c->maxLogFileSizeInKB));
CheckError(GetDWORD(section, L"maxLogFiles", &c->maxLogFiles));
CheckError(GetBOOL(section, L"loggingEnabled", &c->loggingEnabled));
CheckError(GetBOOL(section, L"appendToExistingLog", &c->appendToExistingLog));
CheckError(GetBOOL(section, L"devErrorsEnabled", &c->devErrorsEnabled));
CheckError(GetBOOL(section, L"flushResponse", &c->flushResponse));
CheckError(GetString(section, L"logDirectoryNameSuffix", &c->logDirectoryNameSuffix));
CheckError(GetString(section, L"logDirectory", &c->logDirectory));
CheckError(GetBOOL(section, L"debuggingEnabled", &c->debuggingEnabled));
CheckError(GetString(section, L"node_env", &c->node_env));
CheckError(GetString(section, L"debuggerPortRange", &c->debugPortRange));
Expand All @@ -1024,6 +1088,14 @@ HRESULT CModuleConfiguration::GetConfig(IHttpContext* context, CModuleConfigurat
delete [] commandLine;
commandLine = NULL;

// interceptor

CheckError(GetString(section, L"interceptor", &commandLine));
ErrorIf(NULL == (c->interceptor = new char[MAX_PATH]), ERROR_NOT_ENOUGH_MEMORY);
ErrorIf(0 != wcstombs_s(&i, c->interceptor, (size_t)MAX_PATH, commandLine, _TRUNCATE), ERROR_INVALID_PARAMETER);
delete [] commandLine;
commandLine = NULL;

// apply config setting overrides from the optional YAML configuration file

CheckError(CModuleConfiguration::ApplyYamlConfigOverrides(context, c));
Expand Down Expand Up @@ -1097,6 +1169,11 @@ LPCTSTR CModuleConfiguration::GetNodeProcessCommandLine(IHttpContext* ctx)
GETCONFIG(nodeProcessCommandLine)
}

LPCTSTR CModuleConfiguration::GetInterceptor(IHttpContext* ctx)
{
GETCONFIG(interceptor)
}

DWORD CModuleConfiguration::GetMaxConcurrentRequestsPerProcess(IHttpContext* ctx)
{
GETCONFIG(maxConcurrentRequestsPerProcess)
Expand Down Expand Up @@ -1132,9 +1209,9 @@ DWORD CModuleConfiguration::GetGracefulShutdownTimeout(IHttpContext* ctx)
GETCONFIG(gracefulShutdownTimeout)
}

LPWSTR CModuleConfiguration::GetLogDirectoryNameSuffix(IHttpContext* ctx)
LPWSTR CModuleConfiguration::GetLogDirectory(IHttpContext* ctx)
{
GETCONFIG(logDirectoryNameSuffix)
GETCONFIG(logDirectory)
}

LPWSTR CModuleConfiguration::GetDebuggerPathSegment(IHttpContext* ctx)
Expand All @@ -1147,24 +1224,24 @@ DWORD CModuleConfiguration::GetDebuggerPathSegmentLength(IHttpContext* ctx)
GETCONFIG(debuggerPathSegmentLength)
}

DWORD CModuleConfiguration::GetLogFileFlushInterval(IHttpContext* ctx)
DWORD CModuleConfiguration::GetMaxTotalLogFileSizeInKB(IHttpContext* ctx)
{
GETCONFIG(logFileFlushInterval)
GETCONFIG(maxTotalLogFileSizeInKB)
}

DWORD CModuleConfiguration::GetMaxLogFileSizeInKB(IHttpContext* ctx)
{
GETCONFIG(maxLogFileSizeInKB)
}

BOOL CModuleConfiguration::GetLoggingEnabled(IHttpContext* ctx)
DWORD CModuleConfiguration::GetMaxLogFiles(IHttpContext* ctx)
{
GETCONFIG(loggingEnabled);
GETCONFIG(maxLogFiles)
}

BOOL CModuleConfiguration::GetAppendToExistingLog(IHttpContext* ctx)
BOOL CModuleConfiguration::GetLoggingEnabled(IHttpContext* ctx)
{
GETCONFIG(appendToExistingLog)
GETCONFIG(loggingEnabled);
}

BOOL CModuleConfiguration::GetDebuggingEnabled(IHttpContext* ctx)
Expand Down
14 changes: 8 additions & 6 deletions src/iisnode/cmoduleconfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ class CModuleConfiguration : public IHttpStoredContext
DWORD asyncCompletionThreadCount;
DWORD nodeProcessCountPerApplication;
LPTSTR nodeProcessCommandLine;
LPTSTR interceptor;
DWORD maxConcurrentRequestsPerProcess;
DWORD maxNamedPipeConnectionRetry;
DWORD namedPipeConnectionRetryDelay;
DWORD initialRequestBufferSize;
DWORD maxRequestBufferSize;
DWORD uncFileChangesPollingInterval;
DWORD gracefulShutdownTimeout;
LPWSTR logDirectoryNameSuffix;
LPWSTR logDirectory;
LPWSTR debuggerPathSegment;
DWORD debuggerPathSegmentLength;
DWORD logFileFlushInterval;
DWORD maxLogFileSizeInKB;
DWORD maxTotalLogFileSizeInKB;
DWORD maxLogFiles;
BOOL loggingEnabled;
BOOL appendToExistingLog;
BOOL debuggingEnabled;
LPWSTR debugPortRange;
DWORD debugPortStart;
Expand Down Expand Up @@ -70,20 +71,21 @@ class CModuleConfiguration : public IHttpStoredContext
static DWORD GetAsyncCompletionThreadCount(IHttpContext* ctx);
static DWORD GetNodeProcessCountPerApplication(IHttpContext* ctx);
static LPCTSTR GetNodeProcessCommandLine(IHttpContext* ctx);
static LPCTSTR GetInterceptor(IHttpContext* ctx);
static DWORD GetMaxConcurrentRequestsPerProcess(IHttpContext* ctx);
static DWORD GetMaxNamedPipeConnectionRetry(IHttpContext* ctx);
static DWORD GetNamedPipeConnectionRetryDelay(IHttpContext* ctx);
static DWORD GetInitialRequestBufferSize(IHttpContext* ctx);
static DWORD GetMaxRequestBufferSize(IHttpContext* ctx);
static DWORD GetUNCFileChangesPollingInterval(IHttpContext* ctx);
static DWORD GetGracefulShutdownTimeout(IHttpContext* ctx);
static LPWSTR GetLogDirectoryNameSuffix(IHttpContext* ctx);
static LPWSTR GetLogDirectory(IHttpContext* ctx);
static LPWSTR GetDebuggerPathSegment(IHttpContext* ctx);
static DWORD GetDebuggerPathSegmentLength(IHttpContext* ctx);
static DWORD GetLogFileFlushInterval(IHttpContext* ctx);
static DWORD GetMaxLogFileSizeInKB(IHttpContext* ctx);
static DWORD GetMaxTotalLogFileSizeInKB(IHttpContext* ctx);
static DWORD GetMaxLogFiles(IHttpContext* ctx);
static BOOL GetLoggingEnabled(IHttpContext* ctx);
static BOOL GetAppendToExistingLog(IHttpContext* ctx);
static BOOL GetDebuggingEnabled(IHttpContext* ctx);
static HRESULT GetDebugPortRange(IHttpContext* ctx, DWORD* start, DWORD* end);
static LPWSTR GetNodeEnv(IHttpContext* ctx);
Expand Down
Loading

0 comments on commit 7427f22

Please sign in to comment.