Logging Messages
actionETL automatically logs the progress of the worker system and its workers. It is also often useful to log additional information in your own code, both when using workers and when developing new workers. This is done by calling methods on an ALog instance.
Log levels
Log levels are defined by ALogLevel, which contains, from lowest to highest severity:
Level | Description |
---|---|
Trace |
The most detailed and verbose level, e.g. logging individual data rows, detailed progress reporting etc. It is normally too verbose to enable in production. |
Debug |
More verbose than Info , e.g. high level progress reporting, detailed data type information etc. It is normally OK to enable in production. |
Info |
Normally the lowest level being logged, e.g. file processed, query text, column mappings etc. |
Warn |
Warning about a potential issue |
Error |
Actual issue that can potentially be recovered from |
Fatal |
Actual issue that is fatal and can't be recovered from |
Off |
Setting the log threshold to Off turns all logging off (can also be done by injecting a NullLogFactory.Instance when creating the worker system) |
Note
Logging an Error
or Fatal
message won't by itself affect the execution of
the worker system.
Returning an Error
or Fatal
IOutcomeStatus from a worker will however affect it.
ALog Members
Member | Description |
---|---|
Trace() , Debug() , Info() , Warn() , Error() , Fatal() |
Overloads to log a message at the corresponding log level |
ConditionalTrace() , ConditionalDebug() |
Overloads to log a message if Trace / Debug conditional compilation symbol is defined, useful in performance sensitive areas |
Log() |
Overloads to log a message at a specified log level |
IsTraceEnabled, IsDebugEnabled, IsInfoEnabled, IsWarnEnabled, IsErrorEnabled, IsFatalEnabled | True if the corresponding level is enabled, useful for only doing log parameter calculations if they are needed |
IsEnabled() |
Check if a specified log level is enabled |
Factory |
Factory that created the ALog instance, can e.g. flush log messages to their targets |
A log message can be supplied as either a regular string, or as an ALogMessageCallback
that
returns a string. The latter only calculates the string if the specified log level is enabled,
which is another way of only doing some log parameter calculations if they are needed:
Logger.Debug(() => myStatistics.ToString(), ProgressWorker);
ALogCategory
and category
Parameters
When logging messages the category
parameter is mandatory; it's a string that classifies
log messages. The format is "TopCategory.Subcategory1.Subcategory2", where the number of sub
categories is zero or more. This particular format is very useful, since many
log viewers can filter and group log messages based
on this format.
Workers can define their own categories (using this format), but should use the string constants in ALogCategory where appropriate, e.g.:
TargetDoesNotExist
= "Target.DoesNotExist"FileOperationFailed
= "File.Operation.Failed"UnexpectedExceptionUserCode
= "Unexpected.Exception.UserCode"
The category
parameter is by default included in the logging output, see
Logging Configuration File.
Logging in a WorkerSystem
The WorkerSystem, all workers, and all input and output ports have a
Logger
property (e.g. Logger) with an ALog
instance
initialized with the corresponding Locator
string as its name.
This is the normal way for workers and the library user to log messages.
For example, this worker system:
new WorkerSystem("Test").Root(ws =>
{
// ...
ws.Logger.Warn(ALogCategory.SourceDoesNotExists, "source.txt");
}
).Start().Exit();
would log the following to the console:
DateTime | Level | Locator | Category | Message
2020-08-19 16:17:58.9159 | INFO | /Test | System.Status.Created | Type=actionETL.WorkerSystem
2020-08-19 16:17:59.0239 | INFO | /Test | System.Environment | HostName='Boom' UserName='Kristian' CWD='C:\Projects\MinimalFileExists\bin\AnyCPU\Release\net461' ProcessorCount=4 AvailablePhysicalMemBytes=4479717376 TotalPhysicalMemBytes=17105559552 GarbageCollection=Batch,Server Framework='.NET Framework 4.8' CompilePlatform=AnyCPU OsBits=64 ProcessBits=64 OsVersion='Microsoft Windows NT 6.2.9200.0' CurrentCulture='en-GB' UTC='2020-08-19T15:17:58 UTC (+00)' LibraryVersion=0.36.0.5050 MinorVersionReleaseDate=2020-08-19 CreationGuid=b936494c-b70d-49ed-a294-fcd039fd24aa
2020-08-19 16:17:59.2827 | INFO | /Test | System.Status.Running |
2020-08-19 16:17:59.2941 | WARN | /Test | Source.DoesNotExists | source.txt
2020-08-19 16:17:59.3641 | INFO | /Test | System.Statistics.Ending | Started=2020-08-19T15:17:59Z Completed=2020-08-19T15:17:59Z Duration=0:00:00:00.0154456 WorkerTypesUsed=0 PeakPagedMemBytes=58544128 PeakVirtualMemBytes=22817902592 PeakWorkingSetBytes=43118592 UserProcessorTime=00:00:00.625 TotalProcessorTime=00:00:00.781
2020-08-19 16:17:59.3641 | INFO | /Test | System.Status.Completed.Succeeded |
which includes our custom log message with:
- Log level =
Warn
, since we calledWarn()
- Locator = "/Test" since we used the worker system
Logger
property - Category = "Source.DoesNotExists" since we used the corresponding string constant
- Message = "source.txt"
Important
Always use the specific (worker system, worker, or port) Logger
property whose
Locator
string best corresponds to your logging message.
Logging Outside a WorkerSystem
ALog
logger instances can also be created outside any worker system by using
NLogFactory, as shown in
Logging.