Skip to content
Tomasz Cichoń edited this page Nov 15, 2019 · 1 revision

Logging system is your front-line debugging tool. Since Centrifuge 2.0 it has been vastly expanded to allow advanced users for logging events in any way they want. This document aims to explain every detail that will help you take advantage of the full power the logging system offers.

The Basics

Here's how you initialize a logger tied to your mod's assembly with the following defaults:
  ▐ Logs to a console,
  ▐ Logs to a file with the name of your mod's assembly in your mod's directory,
  ▐ Has a 24 hour time stamp, colored log level abbreviation and shows event source class name.
  ▐ Has the output template of [{DateTime} {LogLevel}] [{ClassName}] {Message}.

using Reactor.API.Logging;

// ...

private Log Log => LogManager.GetForCurrentAssembly();

That's it, you can now log events using the following methods.

Logging methods

  ▐ Info(string message)
  ▐ Pushes your message with the LogLevel of Info to all active sinks.

  ▐ Warning(string message)
  ▐ Pushes your message with the LogLevel of Warning to all active sinks.

  ▐ Error(string message)
  ▐ Pushes your message with the LogLevel of Error to all active sinks.

  ▐ Debug(string message)
  ▐ Pushes your message with the LogLevel of Debug to all active sinks.

  ▐ Exception(Exception e)
  ▐ Pushes your message with the LogLevel of Exception to all active sinks.

  ▐ ReflectionTypeLoadException(ReflectionTypeLoadException rtle)
  ▐ Pushes your message with the LogLevel of ReflectionTypeLoadException to all active sinks.

Remarks
The ReflectionTypeLoadException method is a specialized exception logging method allowing you to display loader errors if any DLL fails to load. Helps nail down the source of annoying assembly load bugs.

The advanced stuff

Using more than one log

It is possible to create more than one log that is not tracked in any way by Centrifuge. You are, however, responsible for setting up its target sinks, decorators and the output template, as a 'bare' log provided that way is only supplied with a template that allows it to display just the message it gets. To do that, the following method is used:

  ▐ LogManager.CreateBareLog()
  ▐ Creates an untracked 'bare' log for your mod to configure, manually use and close when it's not needed.

Sinks

A 'sink' is a way for logger to output any data it receives from event sources. It can be - including, but not limited to - terminal, file, database or a network stream. A log can have an unlimited number of sinks, but they all need to be of a unique type.

Creating a sink

The simplest sink that's possible to create with the Reactor.API is most likely the console sink, already included with the API:

using Reactor.API.Logging.Base;

namespace MyExampleMod
{
    public class ConsoleSink : Sink
    {
        public override void Write(LogLevel logLevel, string message, params object[] args)
        {
            Console.WriteLine(message);
        }
    }
}

Aside from the two standard parameters of LogLevel and string, a sink can take any number of object parameters provided by the logging system. This is currently only used to pass exceptions by the internal system pipeline. In the future it's going to be expanded for developers to use.

If you need an example of a parametrized sink, see the StreamSink class.

Sinks also have an "active" state. They can be turned on or off using the following property inherited from Sink.

  ▐ public bool Active { get; set; }
  ▐ Allows you to enable/disable a sink temporarily.

Adding a sink to a log object

There are two ways of adding a sink, depending on whether or not it's parametrized.

  ▐ Log.SinkTo<T>()
  ▐ Adds a parameterless sink to your logger. Requires you to specify a type.

  ▐ Log.SinkTo(Sink sink)
  ▐ Accepts both parametrized and parameterless sinks. Requires you to specify a sink instance.

Decorators

Decorators provide a way for you to add more information to your logger. They co-operate with the output template to provide the final message format to all the active sinks.

Creating a decorator

using Reactor.API.Logging.Base;

namespace MyExampleMod
{
    public class HelloWorldDecorator : Decorator
    {
        public override string Decorate(LogLevel logLevel, string input, string originalMessage, Sink sink)
        {
            return $"Hello, world";
        }
    }
}

ciastex finish it when u wake up ok?