diff --git a/Jenkinsfile b/Jenkinsfile index 4a811d4..c8ce3bf 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,7 +7,7 @@ pipeline { steps { /* calcolo numero versione... diverso x branch MASTER/DEVELOP */ script { - withEnv(['NEXT_BUILD_NUMBER=723']) { + withEnv(['NEXT_BUILD_NUMBER=724']) { // env.versionNumber = VersionNumber(versionNumberString : '3.5.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true) env.versionNumber = VersionNumber(versionNumberString : '3.5.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}') env.versionNumberBeta = VersionNumber(versionNumberString : '3.5.${BUILD_DATE_FORMATTED, "yyMM"}-beta.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}') @@ -42,6 +42,10 @@ pipeline { // Reports lib bat "\"${tool 'MSBuild-15.0'}\" SteamWare.Reports\\SteamWare.Reports.csproj -target:Build /p:Configuration=Release /p:Platform=\"Any CPU\" /p:OutputPath=bin/ /m" }, + LOGGER: { + // Reports lib + bat "\"${tool 'MSBuild-15.0'}\" SteamWare.Logger\\SteamWare.Logger.csproj -target:Build /p:Configuration=Release /p:Platform=\"Any CPU\" /p:OutputPath=bin/ /m" + }, failFast: false) } } @@ -86,6 +90,12 @@ pipeline { // creo package NuGet... con version in modo da fare ANCHE le beta bat "e:\\nuget.exe pack ${WORKSPACE}\\SteamWare.Reports\\SteamWare.Reports.csproj -properties Configuration=${env.config} -Version ${env.packVers}" }, + LOGGER: { + // BUILD Reports lib! + bat "\"${tool 'MSBuild-16.0'}\" SteamWare.Logger\\SteamWare.Logger.csproj -target:Build /p:Configuration=${env.config} /p:Platform=\"Any CPU\" /p:OutputPath=bin/${env.config} /m" + // creo package NuGet... con version in modo da fare ANCHE le beta + bat "e:\\nuget.exe pack ${WORKSPACE}\\SteamWare.Logger\\SteamWare.Logger.csproj -properties Configuration=${env.config} -Version ${env.packVers}" + }, failFast: false) } else @@ -103,6 +113,7 @@ pipeline { // bat "e:\\nuget.exe push SteamWare.${env.versionNumberBeta}.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted" bat "e:\\nuget.exe push SteamWare.${env.packVers}.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted" bat "e:\\nuget.exe push SteamWare.Reports.${env.packVers}.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted" + bat "e:\\nuget.exe push SteamWare.Logger.${env.packVers}.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted" } } } diff --git a/SteamWare.Logger/Logging.cs b/SteamWare.Logger/Logging.cs new file mode 100644 index 0000000..9747b58 --- /dev/null +++ b/SteamWare.Logger/Logging.cs @@ -0,0 +1,37 @@ +using NLog; +using NLog.Config; +using NLog.Targets; + +namespace SteamWare.Log +{ + /// + /// Classe helper x LOG basata su NLog + /// + public static class Log + { + /// + /// S + /// + public static Logger Instance { get; private set; } + static Log() + { +#if DEBUG + // Setup the logging view for Sentinel - http://sentinel.codeplex.com + var sentinalTarget = new NLogViewerTarget() + { + Name = "sentinal", + Address = "udp://127.0.0.1:9999", + IncludeNLogData = false + }; + var sentinalRule = new LoggingRule("*", LogLevel.Trace, sentinalTarget); + LogManager.Configuration.AddTarget("sentinal", sentinalTarget); + LogManager.Configuration.LoggingRules.Add(sentinalRule); + +#endif + + LogManager.ReconfigExistingLoggers(); + + Instance = LogManager.GetCurrentClassLogger(); + } + } +} diff --git a/SteamWare.Logger/NLog.config b/SteamWare.Logger/NLog.config new file mode 100644 index 0000000..8879ef3 --- /dev/null +++ b/SteamWare.Logger/NLog.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + diff --git a/SteamWare.Logger/NLog.xsd b/SteamWare.Logger/NLog.xsd new file mode 100644 index 0000000..16d888c --- /dev/null +++ b/SteamWare.Logger/NLog.xsd @@ -0,0 +1,3556 @@ + + + + + + + + + + + + + + + Watch config file for changes and reload automatically. + + + + + Print internal NLog messages to the console. Default value is: false + + + + + Print internal NLog messages to the console error output. Default value is: false + + + + + Write internal NLog messages to the specified file. + + + + + Log level threshold for internal log messages. Default value is: Info. + + + + + Global log level threshold for application log messages. Messages below this level won't be logged. + + + + + Throw an exception when there is an internal error. Default value is: false. Not recommend to set to true in production! + + + + + Throw an exception when there is a configuration error. If not set, determined by throwExceptions. + + + + + Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false. + + + + + Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false. + + + + + Write timestamps for internal NLog messages. Default value is: true. + + + + + Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false. + + + + + Perform message template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty. + + + + + + + + + + + + + + Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes). + + + + + + + + + + + + + + + + + Prefix for targets/layout renderers/filters/conditions loaded from this assembly. + + + + + Load NLog extensions from the specified file (*.dll) + + + + + Load NLog extensions from the specified assembly. Assembly name should be fully qualified. + + + + + + + + + + Name of the logger. May include wildcard characters ('*' or '?'). + + + + + Comma separated list of levels that this rule matches. + + + + + Minimum level that this rule matches. + + + + + Maximum level that this rule matches. + + + + + Level that this rule matches. + + + + + Comma separated list of target names. + + + + + Ignore further rules if this one matches. + + + + + Rule identifier to allow rule lookup with Configuration.FindRuleByName and Configuration.RemoveRuleByName. + + + + + + + + + + + + + + + Default action if none of the filters match. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file. + + + + + Ignore any errors in the include file. + + + + + + + + Variable value. Note, the 'value' attribute has precedence over this one. + + + + + + Variable name. + + + + + Variable value. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Number of log events that should be processed in a batch by the lazy writer thread. + + + + + Whether to use the locking queue, instead of a lock-free concurrent queue The locking queue is less concurrent when many logger threads, but reduces memory allocation + + + + + Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch + + + + + Action to be taken when the lazy writer thread request queue count exceeds the set limit. + + + + + Limit on the number of requests in the lazy writer thread request queue. + + + + + Time in milliseconds to sleep between batches. (1 or less means trigger on new activity) + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + Delay the flush until the LogEvent has been confirmed as written + + + + + Condition expression. Log events who meet this condition will cause a flush on the wrapped target. + + + + + Name of the target. + + + + + Only flush when LogEvent matches condition. Ignore explicit-flush, config-reload-flush and shutdown-flush + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Number of log events to be buffered. + + + + + Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes. + + + + + Action to take if the buffer overflows. + + + + + Indicates whether to use sliding timeout. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Encoding to be used. + + + + + Instance of that is used to format log messages. + + + + + End of line value if a newline is appended at the end of log message . + + + + + Maximum message size in bytes. + + + + + Indicates whether to append newline at the end of log message. + + + + + Network address. + + + + + Size of the connection cache (number of connections which are kept alive). + + + + + Indicates whether to keep connection open whenever possible. + + + + + Maximum current connections. 0 = no maximum. + + + + + Action that should be taken if the will be more connections than . + + + + + Action that should be taken if the message is larger than maxMessageSize. + + + + + Get or set the SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP. + + + + + Maximum queue size. + + + + + The number of seconds a connection will remain idle before the first keep-alive probe is sent + + + + + NDLC item separator. + + + + + Indicates whether to include source info (file name and line number) in the information sent over the network. + + + + + Renderer for log4j:event logger-xml-attribute (Default ${logger}) + + + + + Indicates whether to include NLog-specific extensions to log4j schema. + + + + + Indicates whether to include contents of the stack. + + + + + Indicates whether to include stack contents. + + + + + Indicates whether to include dictionary contents. + + + + + Indicates whether to include dictionary contents. + + + + + Indicates whether to include call site (class and method name) in the information sent over the network. + + + + + Option to include all properties from the log events + + + + + AppInfo field. By default it's the friendly name of the current AppDomain. + + + + + NDC item separator. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layout that should be use to calculate the value for the parameter. + + + + + Viewer parameter name. + + + + + Whether an attribute with empty value should be included in the output + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) + + + + + Enables output using ANSI Color Codes + + + + + The encoding for writing messages to the . + + + + + Indicates whether the error stream (stderr) should be used instead of the output stream (stdout). + + + + + Indicates whether to auto-check if the console has been redirected to file - Disables coloring logic when System.Console.IsOutputRedirected = true + + + + + Indicates whether to use default row highlighting rules. + + + + + Indicates whether to auto-flush after + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Condition that must be met in order to set the specified foreground and background color. + + + + + Background color. + + + + + Foreground color. + + + + + + + + + + + + + + + + Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used. + + + + + Indicates whether to ignore case when comparing texts. + + + + + Regular expression to be matched. You must specify either text or regex. + + + + + Text to be matched. You must specify either text or regex. + + + + + Indicates whether to match whole words only. + + + + + Background color. + + + + + Foreground color. + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) + + + + + The encoding for writing messages to the . + + + + + Indicates whether to send the log messages to the standard error instead of the standard output. + + + + + Indicates whether to auto-flush after + + + + + Whether to enable batch writing using char[]-buffers, instead of using + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this. + + + + + Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string. + + + + + Name of the database provider. + + + + + Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string. + + + + + Indicates whether to keep the database connection open between the log events. + + + + + Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string. + + + + + Name of the connection string (as specified in <connectionStrings> configuration section. + + + + + Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase. + + + + + Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string. + + + + + Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + Text of the SQL command to be run on each log level. + + + + + Type of the SQL command to be run on each log level. + + + + + + + + + + + + + + + + + + + + + + + Type of the command. + + + + + Connection string to run the command against. If not provided, connection string from the target is used. + + + + + Indicates whether to ignore failures. + + + + + Command text. + + + + + + + + + + + + + + + + + + Database parameter name. + + + + + Layout that should be use to calculate the value for the parameter. + + + + + Database parameter DbType. + + + + + Database parameter size. + + + + + Database parameter precision. + + + + + Database parameter scale. + + + + + Type of the parameter. + + + + + Convert format of the database parameter value . + + + + + Culture used for parsing parameter string-value for type-conversion + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Layout that renders event Category. + + + + + Optional entry type. When not set, or when not convertible to then determined by + + + + + Layout that renders event ID. + + + + + Name of the Event Log to write to. This can be System, Application or any user-defined name. + + + + + Name of the machine on which Event Log service is running. + + + + + Maximum Event log size in kilobytes. + + + + + Message length limit to write to the Event Log. + + + + + Value to be used as the event Source. + + + + + Action to take if the message is larger than the option. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Indicates whether to return to the first target after any successful write. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + File encoding. + + + + + Line ending mode. + + + + + Indicates whether to compress archive files into the zip archive format. + + + + + Way file archives are numbered. + + + + + Name of the file to be used for an archive. + + + + + Is the an absolute or relative path? + + + + + Indicates whether to automatically archive log files every time the specified time passes. + + + + + Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: + + + + + Maximum number of archive files that should be kept. + + + + + Indicates whether the footer should be written only when the file is archived. + + + + + Maximum number of log file names that should be stored as existing. + + + + + Is the an absolute or relative path? + + + + + Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation. + + + + + Indicates whether file creation calls should be synchronized by a system global mutex. + + + + + Indicates whether to replace file contents on each write instead of appending log message at the end. + + + + + Indicates whether to write BOM (byte order mark) in created files + + + + + Indicates whether to enable log file(s) to be deleted. + + + + + Name of the file to write to. + + + + + Value specifying the date format to use when archiving files. + + + + + Indicates whether to archive old log file on startup. + + + + + Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong. + + + + + Indicates whether to create directories if they do not exist. + + + + + Indicates whether to delete old log file on startup. + + + + + File attributes (Windows only). + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + Indicates whether concurrent writes to the log file by multiple processes on different network hosts. + + + + + Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity. + + + + + Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger). + + + + + Indicates whether to keep log file open instead of opening and closing it on each logging event. + + + + + Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write + + + + + Indicates whether concurrent writes to the log file by multiple processes on the same host. + + + + + Number of times the write is appended on the file before NLog discards the log message. + + + + + Delay in milliseconds to wait before attempting to write to the file again. + + + + + Log file buffer size in bytes. + + + + + Maximum number of seconds before open files are flushed. If this number is negative or zero the files are not flushed by timer. + + + + + Indicates whether to automatically flush the file buffers after each log message. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Condition expression. Log events who meet this condition will be forwarded to the wrapped target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Windows domain name to change context to. + + + + + Required impersonation level. + + + + + Type of the logon provider. + + + + + Logon Type. + + + + + User account password. + + + + + Indicates whether to revert to the credentials of the process instead of impersonating another user. + + + + + Username to change context to. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Interval in which messages will be written up to the number of messages. + + + + + Maximum allowed number of messages written per . + + + + + Name of the target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Endpoint address. + + + + + Name of the endpoint configuration in WCF configuration file. + + + + + Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply) + + + + + Client ID. + + + + + Indicates whether to include per-event properties in the payload sent to the server. + + + + + Indicates whether to use binary message encoding. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + Layout that should be use to calculate the value for the parameter. + + + + + Name of the parameter. + + + + + Type of the parameter. + + + + + Type of the parameter. Obsolete alias for + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + Indicates whether NewLine characters in the body should be replaced with tags. + + + + + Priority used for sending mails. + + + + + Encoding to be used for sending e-mail. + + + + + BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). + + + + + CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). + + + + + Indicates whether to add new lines between log entries. + + + + + Indicates whether to send message as HTML instead of plain text. + + + + + Sender's email address (e.g. joe@domain.com). + + + + + Mail message body (repeated for each log message send in one mail). + + + + + Mail subject. + + + + + Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + Indicates the SMTP client timeout. + + + + + SMTP Server to be used for sending. + + + + + SMTP Authentication mode. + + + + + Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic"). + + + + + Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic"). + + + + + Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server. + + + + + Port number that SMTP Server is listening on. + + + + + Indicates whether the default Settings from System.Net.MailSettings should be used. + + + + + Folder where applications save mail messages to be processed by the local SMTP server. + + + + + Specifies how outgoing email messages will be handled. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Max number of items to have in memory + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Class name. + + + + + Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Encoding to be used. + + + + + End of line value if a newline is appended at the end of log message . + + + + + Maximum message size in bytes. + + + + + Indicates whether to append newline at the end of log message. + + + + + Network address. + + + + + Size of the connection cache (number of connections which are kept alive). + + + + + Indicates whether to keep connection open whenever possible. + + + + + Maximum current connections. 0 = no maximum. + + + + + Maximum queue size. + + + + + Action that should be taken if the will be more connections than . + + + + + Action that should be taken if the message is larger than maxMessageSize. + + + + + Get or set the SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP. + + + + + The number of seconds a connection will remain idle before the first keep-alive probe is sent + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Encoding to be used. + + + + + Instance of that is used to format log messages. + + + + + End of line value if a newline is appended at the end of log message . + + + + + Maximum message size in bytes. + + + + + Indicates whether to append newline at the end of log message. + + + + + Network address. + + + + + Size of the connection cache (number of connections which are kept alive). + + + + + Indicates whether to keep connection open whenever possible. + + + + + Maximum current connections. 0 = no maximum. + + + + + Action that should be taken if the will be more connections than . + + + + + Action that should be taken if the message is larger than maxMessageSize. + + + + + Get or set the SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP. + + + + + Maximum queue size. + + + + + The number of seconds a connection will remain idle before the first keep-alive probe is sent + + + + + NDLC item separator. + + + + + Indicates whether to include source info (file name and line number) in the information sent over the network. + + + + + Renderer for log4j:event logger-xml-attribute (Default ${logger}) + + + + + Indicates whether to include NLog-specific extensions to log4j schema. + + + + + Indicates whether to include contents of the stack. + + + + + Indicates whether to include stack contents. + + + + + Indicates whether to include dictionary contents. + + + + + Indicates whether to include dictionary contents. + + + + + Indicates whether to include call site (class and method name) in the information sent over the network. + + + + + Option to include all properties from the log events + + + + + AppInfo field. By default it's the friendly name of the current AppDomain. + + + + + NDC item separator. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Indicates whether to perform layout calculation. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Indicates whether performance counter should be automatically created. + + + + + Name of the performance counter category. + + + + + Counter help text. + + + + + Name of the performance counter. + + + + + Performance counter type. + + + + + The value by which to increment the counter. + + + + + Performance counter instance name. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Default filter to be applied when no specific rule matches. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + Condition to be tested. + + + + + Resulting filter to be applied when the condition matches. + + + + + + + + + + + + + Name of the target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + Name of the target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + Number of times to repeat each log message. + + + + + + + + + + + + + + + + + Name of the target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + Number of retries that should be attempted on the wrapped target in case of a failure. + + + + + Time to wait between retries in milliseconds. + + + + + + + + + + + + + + + Name of the target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + Name of the target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Always use independent of + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit + + + + + Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8. + + + + + Web service method name. Only used with Soap. + + + + + Web service namespace. Only used with Soap. + + + + + Protocol to be used when calling web service. + + + + + Custom proxy address, include port separated by a colon + + + + + Encoding. + + + + + Web service URL. + + + + + Value whether escaping be done according to the old NLog style (Very non-standard) + + + + + Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs) + + + + + Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in parameters) + + + + + Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ). + + + + + (optional) root namespace of the XML document, if POST of XML document chosen. (see and ). + + + + + Proxy configuration when calling web service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Footer layout. + + + + + Header layout. + + + + + Body layout (can be repeated multiple times). + + + + + Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom'). + + + + + Column delimiter. + + + + + Quote Character. + + + + + Quoting mode. + + + + + Indicates whether CVS should include header. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layout of the column. + + + + + Name of the column. + + + + + Override of Quoting mode + + + + + + + + + + + + + + + + + + + + + List of property names to exclude when is true + + + + + Option to include all properties from the log event (as JSON) + + + + + Indicates whether to include contents of the dictionary. + + + + + Indicates whether to include contents of the dictionary. + + + + + Indicates whether to include contents of the dictionary. + + + + + How far should the JSON serializer follow object references before backing off + + + + + Option to render the empty object value {} + + + + + Option to suppress the extra spaces in the output json + + + + + Should forward slashes be escaped? If true, / will be converted to \/ + + + + + + + + + + + + + + + + + Layout that will be rendered as the attribute's value. + + + + + Name of the attribute. + + + + + Determines whether or not this attribute will be Json encoded. + + + + + Indicates whether to escape non-ascii characters + + + + + Whether an attribute with empty value should be included in the output + + + + + Should forward slashes be escaped? If true, / will be converted to \/ + + + + + + + + + + + + + + Footer layout. + + + + + Header layout. + + + + + Body layout (can be repeated multiple times). + + + + + + + + + + + + + + + + + + + + + Option to include all properties from the log events + + + + + Indicates whether to include call site (class and method name) in the information sent over the network. + + + + + Indicates whether to include contents of the dictionary. + + + + + Indicates whether to include contents of the dictionary. + + + + + Indicates whether to include contents of the stack. + + + + + Indicates whether to include contents of the stack. + + + + + Indicates whether to include source info (file name and line number) in the information sent over the network. + + + + + + + + + + + + + + Layout text. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + List of property names to exclude when is true + + + + + Option to include all properties from the log event (as XML) + + + + + Indicates whether to include contents of the dictionary. + + + + + Indicates whether to include contents of the dictionary. + + + + + How far should the XML serializer follow object references before backing off + + + + + XML element name to use for rendering IList-collections items + + + + + XML attribute name to use when rendering property-key When null (or empty) then key-attribute is not included + + + + + XML element name to use when rendering properties + + + + + XML attribute name to use when rendering property-value When null (or empty) then value-attribute is not included and value is formatted as XML-element-value + + + + + Name of the root XML element + + + + + Value inside the root XML element + + + + + Whether a ElementValue with empty value should be included in the output + + + + + Auto indent and create new lines + + + + + Determines whether or not this attribute will be Xml encoded. + + + + + + + + + + + + + + + Layout that will be rendered as the attribute's value. + + + + + Name of the attribute. + + + + + Determines whether or not this attribute will be Xml encoded. + + + + + Whether an attribute with empty value should be included in the output + + + + + + + + + + + + + + + + + + + + + + + + + Determines whether or not this attribute will be Xml encoded. + + + + + Name of the element + + + + + Value inside the element + + + + + Whether a ElementValue with empty value should be included in the output + + + + + Auto indent and create new lines + + + + + List of property names to exclude when is true + + + + + Option to include all properties from the log event (as XML) + + + + + Indicates whether to include contents of the dictionary. + + + + + Indicates whether to include contents of the dictionary. + + + + + How far should the XML serializer follow object references before backing off + + + + + XML element name to use for rendering IList-collections items + + + + + XML attribute name to use when rendering property-key When null (or empty) then key-attribute is not included + + + + + XML element name to use when rendering properties + + + + + XML attribute name to use when rendering property-value When null (or empty) then value-attribute is not included and value is formatted as XML-element-value + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + Condition expression. + + + + + + + + + + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + Substring to be matched. + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + String to compare the layout to. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + Substring to be matched. + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + String to compare the layout to. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + + + + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + Default number of unique filter values to expect, will automatically increase if needed + + + + + Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout. + + + + + Layout to be used to filter log messages. + + + + + Max number of unique filter values to expect simultaneously + + + + + Max length of filter values, will truncate if above limit + + + + + How long before a filter expires, and logging is accepted again + + + + + Default buffer size for the internal buffers + + + + + Reuse internal buffers, and doesn't have to constantly allocate new buffers + + + + + Append FilterCount to the when an event is no longer filtered + + + + + Insert FilterCount value into when an event is no longer filtered + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SteamWare.Logger/Properties/AssemblyInfo.cs b/SteamWare.Logger/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..66d492d --- /dev/null +++ b/SteamWare.Logger/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Le informazioni generali relative a un assembly sono controllate dal seguente +// set di attributi. Modificare i valori di questi attributi per modificare le informazioni +// associate a un assembly. +[assembly: AssemblyTitle("SteamWare.Logger")] +[assembly: AssemblyDescription("Classi utility Logging by Steamware")] +[assembly: AssemblyConfiguration("")] +// [assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SteamWare.Logger")] +// [assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("SteamWare")] +[assembly: AssemblyCulture("")] + +// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili +// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da +// COM, impostare su true l'attributo ComVisible per tale tipo. +[assembly: ComVisible(false)] + +// Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi +[assembly: Guid("97a9f482-c173-4f0f-9f8f-7bb41c59cdd6")] + +// Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: +// +// Versione principale +// Versione secondaria +// Numero di build +// Revisione +// +// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build +// usando l'asterisco '*' come illustrato di seguito: +// [assembly: AssemblyVersion("1.0.*")] +//[assembly: AssemblyVersion("1.0.0.0")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SteamWare.Logger/SteamWare.Logger.csproj b/SteamWare.Logger/SteamWare.Logger.csproj new file mode 100644 index 0000000..e0ea9c7 --- /dev/null +++ b/SteamWare.Logger/SteamWare.Logger.csproj @@ -0,0 +1,71 @@ + + + + + Debug + AnyCPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6} + Library + Properties + SteamWare.Log + SteamWare.Log + v4.6.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\NLog.4.6.8\lib\net45\NLog.dll + + + + + + + + + + + + + + + + + + SteamWare.cs + + + + + + + PreserveNewest + + + Always + + + Designer + + + + + \ No newline at end of file diff --git a/SteamWare.Logger/log2note.cs b/SteamWare.Logger/log2note.cs new file mode 100644 index 0000000..3e07dcf --- /dev/null +++ b/SteamWare.Logger/log2note.cs @@ -0,0 +1,316 @@ +using System; + +namespace SteamWare.Log +{ + /// + /// classe gestione logging esteso di eventi e note utente (correlabili) + /// + public class log2note + { + #region area protected + + /// + /// TableAdapter di accesso alla tabella anagrafica filtraggi + /// + protected DS_loggingTableAdapters.T_anagFiltroTableAdapter taAnagFilt; + /// + /// TableAdapter di accesso alla tabella anagrafica record + /// + protected DS_loggingTableAdapters.T_anagRecordTableAdapter taAnagRec; + /// + /// TableAdapter di accesso alla tabella logging record di eventi + /// + protected DS_loggingTableAdapters.T_logRecordsTableAdapter taLogRec; + /// + /// TableAdapter di accesso alla tabella logging utente + /// + protected DS_loggingTableAdapters.T_logUtenteTableAdapter taLogUt; + /// + /// TableAdapter di accesso alla vista logging eventi + /// + public DS_loggingTableAdapters.v_logRecordsTableAdapter ta_vLogRec; + /// + /// TableAdapter di accesso alla vista logging utente + /// + public DS_loggingTableAdapters.v_logUtenteTableAdapter ta_vLogUt; + + /// + /// effettua setup dei connection strings da web.config delal singola applicazione + /// + protected void setupConnectionString() + { + // cambio le connString + string _connectionString = memLayer.ML.confReadString("LoggingConnectionString"); + taAnagFilt.Connection.ConnectionString = _connectionString; + taAnagRec.Connection.ConnectionString = _connectionString; + taLogRec.Connection.ConnectionString = _connectionString; + taLogUt.Connection.ConnectionString = _connectionString; + ta_vLogUt.Connection.ConnectionString = _connectionString; + ta_vLogRec.Connection.ConnectionString = _connectionString; + } + /// + /// avvio i tari tableAdapters + /// + private void setupTA() + { + taAnagFilt = new DS_loggingTableAdapters.T_anagFiltroTableAdapter(); + taAnagRec = new DS_loggingTableAdapters.T_anagRecordTableAdapter(); + taLogRec = new DS_loggingTableAdapters.T_logRecordsTableAdapter(); + taLogUt = new DS_loggingTableAdapters.T_logUtenteTableAdapter(); + ta_vLogRec = new DS_loggingTableAdapters.v_logRecordsTableAdapter(); + ta_vLogUt = new DS_loggingTableAdapters.v_logUtenteTableAdapter(); + } + /// + /// avvio della classe istanziando db e + /// + log2note() + { + setupTA(); + setupConnectionString(); + } + + + #endregion + + #region area public + + /// + /// oggetto statico di accesso ai metodi della classe... + /// + public static log2note l2n = new log2note(); + + #region area oggetti restituiti + + /// + /// tabella eventi + /// + /// + public DS_logging.v_logRecordsDataTable tabLogEventi() + { + return ta_vLogRec.GetData(); + } + /// + /// tabella note + /// + /// + public DS_logging.v_logUtenteDataTable tabLogNote() + { + return ta_vLogUt.GetData(); + } + /// + /// tabella eventi secondo filtro + /// + /// filtro gestito come condizione "LIKE '%{0}%'" rispetto al filtro salvato con l'evento + /// + public DS_logging.v_logRecordsDataTable tabLogEventi(string filtro) + { + return ta_vLogRec.getByFiltro(filtro); + } + /// + /// tabella note secondo filtro + /// + /// filtro gestito come condizione "LIKE '%{0}%'" rispetto al filtro salvato con l'evento + /// + public DS_logging.v_logUtenteDataTable tabLogNote(string filtro) + { + return ta_vLogUt.getByFiltro(filtro); + } + /// + /// tabella eventi secondo filtro e condizione ulteriore WHERE esplicitata + /// + /// filtro gestito come condizione "LIKE '%{0}%'" rispetto al filtro salvato con l'evento + /// ulteriore condizione WHERE per filtrare i dati (testo {0} della condizione "WHERE {0}" + /// + public DS_logging.v_logRecordsDataTable tabLogEventi(string filtro, string _where) + { + DS_logging.v_logRecordsDataTable _tab = new DS_logging.v_logRecordsDataTable(); + foreach (DS_logging.v_logRecordsRow riga in ta_vLogRec.getByFiltro(filtro).Select(_where)) + { + _tab.Addv_logRecordsRow(riga); + } + return _tab; + } + /// + /// tabella note secondo filtro e condizione ulteriore WHERE esplicitata + /// + /// filtro gestito come condizione "LIKE '%{0}%'" rispetto al filtro salvato con l'evento + /// ulteriore condizione WHERE per filtrare i dati (testo {0} della condizione "WHERE {0}" + /// + public DS_logging.v_logUtenteDataTable tabLogNote(string filtro, string _where) + { + DS_logging.v_logUtenteDataTable _tab = new DS_logging.v_logUtenteDataTable(); + foreach (DS_logging.v_logUtenteRow riga in ta_vLogUt.getByFiltro(filtro).Select(_where)) + { + _tab.Addv_logUtenteRow(riga); + } + return _tab; + } + + /// + /// tabella note secondo filtro + /// + /// filtro gestito come condizione "LIKE '%{0}%'" rispetto al filtro salvato con l'evento + /// + public DS_logging.T_logUtenteDataTable tabLogUt(string filtro) + { + return taLogUt.getByFiltro(filtro); + } + + + #endregion + + #region area insert valori + + /// + /// inserisce l'evento indicato dai parametri + /// + /// user che ha generato l'evento + /// pagina/form applicaizone in cui l'evento si è generato + /// valore originale(se c'è) + /// valore nuovo/modificato + /// descrizione evento (poi gestita con anagrafica interna) + /// filtro logico evento (poi gestita con anagrafica interna) + public void insEvento(string _userEv, string _pagina, string _valOrig, string _valNew, string _evento, string _filtro) + { + taLogRec.sp_insRecFull(_userEv, _pagina, _valOrig, _valNew, _evento, _filtro); + } + /// + /// inserisce la nota utente indicata dai parametri, restituisce idx della nota creata... + /// + /// user che ha inserito la nota + /// testo della nota + /// valore ulteriore da associare alla nota (es: label, codice, versione, ...) + /// filtro logico evento (poi gestita con anagrafica interna) + /// intero dell'idx della nota creata + public int insNota(string _userNota, string _nota, string _val, string _filtro) + { + int? answ = 0; + taLogUt.sp_insLogUtFull(_userNota, _nota, _val, _filtro, ref answ); + return (int)answ; + } + + #endregion + + #region area gestione eventi (cestina, delete, associazione a note,...) + + /// + /// associa l'evento e la nota indicati + /// + /// idx del record da associare + /// idx chiave della nota da associare + public void associaEvento2Nota(int idxRecord, int _idxNota) + { + taLogRec.sp_setRec2nota(idxRecord, _idxNota); + } + + /// + /// associa l'ultimo evento del filtro indicato alla nota + /// + /// filtro associato all'ultimo evento... + /// idx chiave della nota da associare + public void associaLastEvento2Nota(string filtro, int _idxNota) + { + taLogRec.sp_setLastRec2nota(filtro, _idxNota); + } + /// + /// segna come cestinati tutti gli eventi dell'utente indicato non ancora associati o cestinati + /// + /// utente generatore dell'evento + public void cestinaEventiUser(string _userEv) + { + taLogRec.sp_cestinaLogRecUt(_userEv); + } + /// + /// segna come cestinati tutti gli eventi dell'utente indicato non ancora associati o cestinati + /// + /// utente generatore dell'evento + public void cestinaEventiFiltro(string _filtro) + { + taLogRec.sp_cestinaLogRecFiltro(_filtro); + } + /// + /// Elimina gli eventi cestinati generati dall'utente indicato + /// + /// utente generatore dell'evento + public void eliminaEventiDaUser(string _userEv) + { + taLogRec.sp_deleteLogUser(_userEv); + } + /// + /// Elimina gli eventi cestinati anteriori alla data selezionata + /// + /// dataOra dell'evento + public void associaEvento2Nota(DateTime _dataOra) + { + taLogRec.sp_deleteLogMaxData(_dataOra); + } + + /// + /// effettua la registrazione dell'evento in session + /// + public void registraEventi(string _userEv, string _pagina) + { + // controllo: loggin SOLO se la scheda ha logging abilitato nella riga del db... + bool logEn = memLayer.ML.BoolSessionObj("logEn"); + memLayer.ML.emptySessionVal("logEn"); + if (logEn) + { + // leggo e svuoto info x logging + string ev2log = memLayer.ML.StringSessionObj("ev2log"); + memLayer.ML.emptySessionVal("ev2log"); + string valOrig = memLayer.ML.StringSessionObj("valOrig"); + memLayer.ML.emptySessionVal("valOrig"); + string valNew = memLayer.ML.StringSessionObj("valNew"); + memLayer.ML.emptySessionVal("valNew"); + string filtEv = memLayer.ML.StringSessionObj("filtEv"); + memLayer.ML.emptySessionVal("filtEv"); + // effettuo logging evento + l2n.insEvento(_userEv, _pagina, valOrig, valNew, ev2log, filtEv); + } + } + + #endregion + + #endregion + } + /// + /// metodo di comportamento del controllo di logging + /// + public enum logControlMode + { + /// + /// nasconde pannello log + /// + hideLog, + /// + /// memorizza log inserito + /// + recordLog, + /// + /// mostra pannello log + /// + showLog + } + /// + /// metodo di comportamento del controllo di logging + /// + public enum tipoApprovazione + { + /// + /// indica il primo step del doppio livello di approvazione (completamento) + /// + completamento, + /// + /// SOLO con incremento indice di revisione dell'oggetto approvato + /// + revisione, + /// + /// SOLO mantenendo indice di revisione corrente + /// + semplice, + /// + /// permette SIA con revisione che senza (e anche rev -1) + /// + tutto + } +} diff --git a/SteamWare.Logger/logger.cs b/SteamWare.Logger/logger.cs new file mode 100644 index 0000000..b7b6ab3 --- /dev/null +++ b/SteamWare.Logger/logger.cs @@ -0,0 +1,500 @@ +using System; +using System.IO; +using System.Threading; + +namespace SteamWare.Log +{ + /// + /// classe gesione log files applicazioni + /// + public class logger + { + #region dichiarazione variabili + + /// + /// directory base x logs + /// + protected string _logBaseDir; + /// + /// nome del file corrente + /// + protected string _logfileName; + /// + /// max mb di log da accumulare + /// + protected int _logMaxMb; + /// + /// controlla se si debba mantenere sotto controllo la dimensioen della cartella logs + /// + protected bool _doShrinkFolder; + /// + /// Ultima verifica directory (x shrink) + /// + private static DateTime lastDirCheck; + /// + /// metodo gestione wirteLock su file log + /// + private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim(); + /// + /// Indica se sia abilitato log diagnostico esteso... + /// + protected bool enableDumpDiag = false; + + #endregion + + #region metodi esposti + + /// + /// singleton del logger + /// + public static logger lg = new logger(); + + /// + /// avvio del logger nella dir desiderata + /// + public logger() + { + string _logDir = memLayer.ML.confReadString("_logDir"); + try + { + _logBaseDir = SteamwareStrings.getFilePath(_logDir); + } + catch (Exception exc) + { + _logBaseDir = _logDir != "" ? _logDir : "~/logs/"; + } + _logMaxMb = 100; // di default 100 mb... + try + { + _doShrinkFolder = memLayer.ML.confReadBool("doShrinkFolder"); + } + catch + { + _doShrinkFolder = true; + } + try + { + enableDumpDiag = memLayer.ML.confReadBool("enableDumpDiag"); + } + catch + { + enableDumpDiag = false; + } + // all'avvio imposto ultimo check a 23 ore fa... così farà shrink DOPO 1 h da avvio + lastDirCheck = DateTime.Now.AddHours(-23); + } + /// + /// livello di log applicazione (da web.config, chiave '_logLevel') + /// + public int logLevel + { + get + { + int answ = -1; + try + { + answ = memLayer.ML.CRI("_logLevel"); + } + catch + { + scriviLog("non ho trovato chiave di registro x logLevel...", tipoLog.ERROR); + } + return answ; + } + } + /// + /// avvio del logger nella dir desiderata + /// + public logger(string _baseDir) + { + _logBaseDir = _baseDir; + _logMaxMb = 40; // di default 40 mb... + } + /// + /// avvio del logger nella dir desiderata con il max di dati indicato + /// + public logger(string _baseDir, int _logMaxMB) + { + _logBaseDir = _baseDir; + _logMaxMb = _logMaxMB; + } + /// + /// resetta il logfile odierno + /// + public void resetLogFile() + { + newLogfileName(); + FileInfo fi = new FileInfo(_logfileName); + fi.Delete(); + scriviLog("ResetFile", tipoLog.STARTUP); + } + /// + /// scrive sul file log di default il valore della variabile string passata su una riga... (tab delim?!?) + /// + /// testo iniziale del log + /// + public bool scriviLog(string _testoPre) + { + bool needWrite = false; + bool fatto = false; + // preparo hash redis + string hKey = _testoPre.Replace(":", "_").Replace("/", "_").Replace("#", "_").Replace("(", "").Replace(")", "").Replace("|", "_").Replace(" ", "_").Replace("__", "_").Replace("__", "_").Replace("__", "_").Replace("__", "_"); + //se troppo lunga trimmo... + if (hKey.Length > 100) + { + hKey = hKey.Substring(0, 100); + } + string hVetoErrore = memLayer.ML.redHash("Logger:Veto:" + hKey); + string hCountErrore = memLayer.ML.redHash("Logger:Counter:" + hKey); + bool redisEnabled = memLayer.ML.confReadBool("cacheOnRedis"); + // verifico mitigazione + int logMitigSec = 30; + try + { + if (memLayer.ML.confReadString("logMitigSec") != "") + { + logMitigSec = memLayer.ML.confReadInt("logMitigSec"); + } + } + catch + { } + // verifico SE HO redis (in quel caso gli errori li loggo 1 volta poi metto un VETO ed un counter) + if (redisEnabled) + { + // cerco se ho un veto precedente in redis + string vetoPar = memLayer.ML.getRSV(hVetoErrore); + if (vetoPar != null && vetoPar != "") + { + needWrite = false; + } + else + { + // metto veto per TTL default... (durata std = 30 sec) + memLayer.ML.setRSV(hVetoErrore, DateTime.UtcNow.ToString(), logMitigSec); + // abilito log... + needWrite = true; + } + memLayer.ML.setRCntI(hCountErrore); + } + else + { + // altrimenti log direttamente + needWrite = true; + } + // se devo DAVVERO scrivere + if (needWrite) + { + if (redisEnabled) + { + int numRep = memLayer.ML.getRCnt(hCountErrore); + if (numRep > 1) + { + // cambio messaggio con un inizio pari al num di ripetizioni... + _testoPre = string.Format("{0} x {1}", numRep, _testoPre); + } + // reset counter + memLayer.ML.resetRCnt(hCountErrore); + } + fatto = doScriviLog(_testoPre); + } + return fatto; + } + /// + /// Vera chiamata scrittura log x override con gestione REDIS di calmierazione + /// + /// + /// + private bool doScriviLog(string _testoPre) + { + bool fatto = false; + // attenzione: rimpiazzo eventuali "
" con newline... + string _testo = string.Format("{0:H:mm:ss ffff} \t{1}", DateTime.Now, _testoPre.Replace("
", Environment.NewLine).Replace("
", Environment.NewLine).Replace("
", Environment.NewLine)); + // se è configurato x shrink ed è passato almeno 1 gg da ultimo check... + if (_doShrinkFolder && lastDirCheck.AddDays(1) < DateTime.Now) + { + // verifica dim directory ed eventualmente cancella... - opzionale + shrinkDir(); + // salvo nuova ora di check + lastDirCheck = DateTime.Now; + } + // (ri)genera il nome del file di log... + newLogfileName(); + // scrivo thread safe + fatto = WriteToFileThreadSafe(_logfileName, _testo); + return fatto; + } + + /// + /// Esecuzione scrittura ThreadSafe + /// + /// + /// + public bool WriteToFileThreadSafe(string logPath, string text2write) + { + bool answ = false; + // Set Status to Locked + _readWriteLock.EnterWriteLock(); + try + { + // Append text to the file + using (StreamWriter sw = File.AppendText(logPath)) + { + sw.WriteLine(text2write); + sw.Close(); + answ = true; + } + } + finally + { + // Release lock + _readWriteLock.ExitWriteLock(); + } + return answ; + } + + /// + /// scrive un messaggio di log con etichetta pre + /// + /// testo messaggio + /// tipo di log da registrare (etichetta [...]) + /// + public bool scriviLog(string testoLog, tipoLog tipo) + { + bool answ = false; + answ = scriviLog(string.Format("[{0}] - {1}", tipo, testoLog)); + // se è un tipo EXCEPTION allora scrivo anche log diagnostico + if (tipo == tipoLog.EXCEPTION && enableDumpDiag) + { + try + { + string[] pingTagets = SteamWare.StringSplitter.CSplitter.Split(memLayer.ML.CRS("pingTargets"), "#", true, -1, SteamWare.StringSplitter.ComparisonMethod.Text); + string[] wwwTagets = SteamWare.StringSplitter.CSplitter.Split(memLayer.ML.CRS("wwwTargets"), "#", true, -1, SteamWare.StringSplitter.ComparisonMethod.Text); + // chiamo scrittura diagnostica + scriviDiagnostica("DUMP diagnostico causa Eccezione", pingTagets, wwwTagets); + } + catch + { } + } + return answ; + } + /// + /// scrive su log un dump di diagnostica + /// + /// Causale diagnostica + /// target per test PING + /// target x download www page + public void scriviDiagnostica(string testoLog, string[] pingTargets, string[] wwwTargets) + { + string txtDiag = ""; + try + { + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, SteamwareStrings.charLine('+', 80))); + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, SteamwareStrings.charLine('+', 80))); + scriviLog(string.Format("[{0}] - {1}{2}", tipoLog.DUMP_DIAGN, testoLog, Environment.NewLine)); + } + catch + { } + + try + { + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, formDiagBlock("UPTIME", Diagnostica.uptime))); + } + catch + { } + + try + { + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, formDiagBlock("STORAGE", Diagnostica.diskUsage))); + } + catch + { } + + try + { + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, formDiagBlock("USB", Diagnostica.usbDevices))); + } + catch + { } + + try + { + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, formDiagBlock("SERIAL", Diagnostica.serialPorts))); + } + catch + { } + + try + { + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, formDiagBlock("NETWORKING (interfaces)", Diagnostica.networkInterfaces))); + } + catch + { } + + try + { + // se richiesto faccio PING test + if (pingTargets.Length > 0) + { + txtDiag = ""; + foreach (string target in pingTargets) + { + txtDiag += SteamwareStrings.addLine(Diagnostica.pingIp(target)); + } + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, formDiagBlock("NETWORKING (ping)", txtDiag))); + } + } + catch + { } + + try + { + // se richiesto faccio PING test + if (wwwTargets.Length > 0) + { + txtDiag = ""; + foreach (string target in wwwTargets) + { + txtDiag += SteamwareStrings.addLine(string.Format("WebPage Test ({2}): {0}{1}", Environment.NewLine, Diagnostica.getPageContent(target), target)); + } + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, formDiagBlock("NETWORKING (www)", txtDiag))); + } + } + catch + { } + + // chiudo + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, SteamwareStrings.charLine('-', 80))); + scriviLog(string.Format("[{0}]{1}{2}", tipoLog.DUMP_DIAGN, Environment.NewLine, SteamwareStrings.charLine('-', 80))); + } + /// + /// formatta un blococ di diagnostica (titolo, contenuto / eccezione) + /// + /// + /// + /// + protected string formDiagBlock(string titolo, string contenuto) + { + string answ = SteamwareStrings.charTitle(titolo, '-', 60); + try + { + answ += SteamwareStrings.addLine(contenuto); + } + catch + { + answ += string.Format("Errore diagnostica {0}", titolo); + } + return answ; + } + + + #endregion + + #region metodi privati + + /// + /// fornisce il nome del file in cui loggare (ed eventualmente crea...) + /// + protected void newLogfileName() + { + DateTime CurrentDateTime = DateTime.Now; + _logfileName = _logBaseDir + String.Format("{0}.log", CurrentDateTime.ToString("yyyyMMdd")); + } + /// + /// provvede a verificare la dim della cartella dei log e cancella i + vecchi fino a restare a dim inferiori a _logMaxMb + /// + protected void shrinkDir() + { + // ottengo elenco files *.log + fileMover.obj.setDirectory(_logBaseDir); + FileInfo[] _fis = fileMover.obj.elencoFiles_FI("*.log"); + compressAndRemove(_fis); + // acnhe per i "Vecchi" formati .txt + _fis = fileMover.obj.elencoFiles_FI("*.txt"); + compressAndRemove(_fis); + } + + private void compressAndRemove(FileInfo[] _fis) + { + foreach (FileInfo _file in _fis) + { + if (_file.CreationTime < DateTime.Now.AddDays(-2)) // zippo files + vecchi di 2 gg... + { + fileMover.obj.zippaSingoloFile(_file); + // cancello l'originale... + fileMover.obj.eliminaFile(_file); + } + } + // verifico directory e dimensione... + while (fileMover.obj.totalMb() > _logMaxMb) + { + // cancello i + vecchi fino a rientrare alla dimensione max... + fileMover.obj.deleteOldest(); + } + } + + /// + /// fornisce il file + vecchio + /// + /// + /// + protected void deleteOldest(DirectoryInfo _di) + { + FileInfo[] _fis = _di.GetFiles(); + DateTime _oldest = DateTime.Now; + string _nome = ""; + foreach (FileInfo _file in _fis) + { + if (_file.CreationTime < _oldest) + { + _nome = _file.Name; + } + } + FileInfo fi = new FileInfo(_nome); + fi.Delete(); + } + + #endregion + } + /// + /// tipo di log ammesso + /// + public enum tipoLog + { + /// + /// informazioni di debug + /// + DEBUG, + /// + /// dump diagnostica + /// + DUMP_DIAGN, + /// + /// errori + /// + ERROR, + /// + /// eccezioni nell'esecuzione try/catch + /// + EXCEPTION, + /// + /// errori fatali + /// + FATAL, + /// + /// informazioni opzionali + /// + INFO, + /// + /// log dei lemmi invocati per traduzione da vocabolario + /// + LEMMA, + /// + /// fase di avvio componente + /// + STARTUP, + /// + /// avvisi + /// + WARNING + } +} diff --git a/SteamWare.Logger/logs/.placeholder b/SteamWare.Logger/logs/.placeholder new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/SteamWare.Logger/logs/.placeholder @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SteamWare.Logger/packages.config b/SteamWare.Logger/packages.config new file mode 100644 index 0000000..02958e8 --- /dev/null +++ b/SteamWare.Logger/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SteamWare.Reports/SteamWare.Reports.csproj b/SteamWare.Reports/SteamWare.Reports.csproj index 02f8b44..e124d25 100644 --- a/SteamWare.Reports/SteamWare.Reports.csproj +++ b/SteamWare.Reports/SteamWare.Reports.csproj @@ -32,7 +32,12 @@ + + + + + @@ -41,9 +46,13 @@ + + SteamWare.cs + + \ No newline at end of file diff --git a/SteamWare.sln b/SteamWare.sln index 7b5668d..1e7869a 100644 --- a/SteamWare.sln +++ b/SteamWare.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBench", "TestBench\Test EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamWare.Reports", "SteamWare.Reports\SteamWare.Reports.csproj", "{1792D70C-D854-415B-ACF1-76BBCB8AC6FE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamWare.Logger", "..\..\..\VisualStudioProject\SteamWare\SteamWare.Logger\SteamWare.Logger.csproj", "{97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|.NET = Debug|.NET @@ -53,6 +55,18 @@ Global {1792D70C-D854-415B-ACF1-76BBCB8AC6FE}.Release|Any CPU.Build.0 = Release|Any CPU {1792D70C-D854-415B-ACF1-76BBCB8AC6FE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {1792D70C-D854-415B-ACF1-76BBCB8AC6FE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Debug|.NET.ActiveCfg = Debug|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Debug|.NET.Build.0 = Debug|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Release|.NET.ActiveCfg = Release|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Release|.NET.Build.0 = Release|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Release|Any CPU.Build.0 = Release|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {97A9F482-C173-4F0F-9F8F-7BB41C59CDD6}.Release|Mixed Platforms.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE