Table of Contents

Namespace ToSic.Sys.Logging

The EAV system has a powerful internal logging system. It's the backbone to Insights.

This is where it resides - usually you don't want to know about it ;).

Tip

This is very internal, and can change at any time. In future, we will make it more aligned with the .NET logging system, but for now it's a custom implementation which is very powerful and flexible.

Warning

This is the internal logging system, which is not the same as the Log object on custom Razor / WebApi code. The custom code logging is a wrapper around this, but it has a different API and is not as powerful as this internal logging system.

This should give you some minimal guidance into logging what your code does.

The General Concept

  1. Most objects have a Log where they add notes about what they are doing - it's a ILog
  2. When objects create child-objects they link their logs so that we have a call hierarchy
  3. Most calls in the objects will declare that they opened a function, log that, and log the result or a comment

With this we can easily see what the code did in the Insights.

Tip

The real power comes from chaining these - because each logger can know what parent-logger it reports to.
This allows us to reproduce the chain of events in the original code, because you can track where
loggers were made, and how they relate.

The really amazing bit is that the logger will also pick up the class names, code-file names and line of code where it was logged 😎.

  • Most objects which use the Log, implement the ToSic.Sys.Logging.IHasLog which automates things when initializing - like the chaining of the Loggers.

How to Use in Your Code

If you create code to extend 2sxc, you may want to use the logger as well. We strongly suggest that you use the same concepts in your code. You'll have to look at the 2sxc/EAV source in Github to discover more.

Log Linking

For optimal log structures, they should be linked together. This helps to show the call hierarchy in the Insights.

This is fully automated, if you adhere to the conventions. Best use the ServiceBase in the ToSic.Sys.Services namespace, which will take care of this for you. It works as follows:

  1. Any object inheriting from ServiceBase
    1. should call base(logName, connect: [service1, service2, service3]) from the constructor.
  2. Any object inheriting from ServiceBase<Dependencies>
    1. should pass the dependencies into the base constructor.
    2. The dependencies are then available on a Services property.
    3. For this to work, the Dependencies should inherit from ToSic.Sys.Services.DependenciesBase or ToSic.Sys.Services.DependenciesRecord.

Logging

Basic Messages

You can log messages with the following methods (they are kept very short to keep the code compact):

  1. Log.A - add a message
  2. Log.W - add a warning
  3. Log.E - add an error

All of these methods have a first string parameter containing the message to add.

They also all have an optional parameter called timer. If this is set to true using timer: true then the log will also contain the time it took to execute the method.

Exceptions

You can log exceptions with the following methods:

  1. Log.Ex - add an exception

Log Properties

Properties use getters and setters. To log these, you must consider a few aspects:

  • do you want to log every single get/set? Or just the first one?
  • do you want to log both get/set or just one of them?

To do this, you have 3 tools at your disposal:

  • Getter(() => result) - this will log the result of the getter
  • Setter(() => result) - this will log the result of the setter
  • Create a GetOnce<T> helper and on the get include the Log - this will only log the initial creation / get of the result

Log Methods, Functions, Properties

TODO:


History

  1. Introduced in 2sxc 9.6
  2. Added 2sxc Insights (server-side) v9.31
  3. Major enhancements in v10.22
  4. Moved to ToSic.Sys.Logging in v15.0

Classes

CodeRef

Reference to source code. It contains the path to the file, the method name and the line in the code.

This is used to track the exact location in the code where a log was added/created.

IHasLogExtensions

Extension to objects having a Log, to connect them to parent logs.

ILogCallExtensions

Extensions for ILogCall objects which don't need to return a value.

ILogExtensions

Various extensions for ILog objects to add logs. They are all implemented as extension methods, so that they will not fail even if the log object is null.

ILog_Actions

Extension methods for Actions (functions which don't return a value).

ILog_Add

Various extensions for ILog objects to add logs. They are all implemented as extension methods, so that they will not fail even if the log object is null.

ILog_Properties

Extension methods for property getters and setters.

LogConstants

Interfaces

ICanDebug

Trivial interface just to ensure that we have debug on/off consistent

ICanDump

Interface to mark classes which can dump their state into the log as a string.

IHasLog

Objects which can log their activity, and share their log with other objects in the chain to produce extensive internal logging.

ILog

A logger with special capabilities. It can take log messages, and chain itself to other loggers.
If chained, it can broadcast the messages to the other loggers from that time forward. Basically this is the backbone of Insights.

To add messages/logs of all kinds you must use null-safe extension methods. It will require you to add the namespace ToSic.Sys.Logging.

ILogCall

A log object used to log the activity of a specific function call. It is usually created in the beginning of the call and closed on various return calls or at the end of the function.

Note that most of the methods used to complete a call are extension methods.

ILogCall<T>

A mini logger for a function call, which should be closed using a form of Return(...) when the function completes.

ILogStore

Interface to add ILogs to the log storage.