Structured logging library for Roblox, akin to (and inspired by) serilog. It uses the Message Templates spec for handling logging.
To begin, you will need to install the package. This can be done via
npm i @rbxts/log
Once installed, to begin logging you will need to configure the logger. (The server/client will need separate configurations, this is the recommended way of doing it)
Basic setup:
import Log, { Logger } from "@rbxts/log";
Log.SetLogger(
Logger.configure()
.WriteTo(Log.RobloxOutput()) // WriteTo takes a sink and writes to it
.Create() // Creates the logger from the configuration
);
Log.Info("Hello, Log!");
The main power of this library comes from the structured event data logging:
const startPoint = new Vector2(0, 0)
const position = new Vector2(25, 134);
const distance = position.sub(startPoint).Magnitude;
Log.Info("Walked to {@Position}, travelling a distance of {Distance}", position, distance);
Log uses message templates, like serilog and will format strings with named parameters (positional coming soon).
The example above has two properties, Position
and Distance
, in the log event the @
operator in front of position tells Log to serialize the object passed in, rather than using tostring(value)
. The listed data types this library can serialize is listed below.
Rendered into JSON using HttpService
, these properties appear alongside the Timestamp, Level and Template like:
{"Position": {"X": 25, "Y": 134}, "Distance": 136.32 }
The structured nature of the data means that it is easily searched and filtered by external tools (as well as roblox-based libraries like Zircon
)
Of course, this data can be logged to the roblox console or another supported console directly if need be, the default Roblox Output sink for example displays the above as such:
08:29:20 [INF] Walked to {"X": 25, "Y": 134}, travelling a distance of 136.32
- Level-based logging, with levels like
Debug
,Information
,Warning
andError
. - Support for custom sinks, like logging to your own external server or to a console like the roblox output and Zircon.
- The ability to enrich logging events using
EnrichWithProperty
orEnrich
. E.g. add the version to your logging events:Log.SetLogger( Logger.configure() // ... .EnrichWithProperty("Version", PKG_VERSION) // Will add "Version" to the event data // ... .Create() );
- A global
Log
object, with the ability to create individualLogger
objects.
Sink Name | Via | Information |
---|---|---|
Roblox Output | Log.RobloxOutput() |
Built in sink which will write to the output + dev console |
Zircon | Zircon.Log.Console() |
Runtime Debugging Console for Roblox |
Use with Flamework
Flamework is a very useful dependency injection transformer for roblox-ts, in which we can use @rbxts/log
quite extensively like you would with regular DI.
A simple approach to the DI logging is to just use ForContext
- however, this is a bit more work and more explicit.
@Service()
export class MyService {
public readonly logger = Log.ForContext(MyService);
}
Instead, we can use the dependency resolution feature of Flamework so that we can just refer to the Logger
object from the constructor :-
(e.g. in index.server.ts
& index.client.ts
)
import Log, { Logger } from "@rbxts/log";
Modding.registerDependency<Logger>((ctor) => {
return Log.ForContext(ctor); // will register this under the given DI class
});
Then in our above example:
@Service()
export class MyService {
public constructor(private readonly logger: Logger) {}
}