Building Game Engine In Rust: Logging (part 3)
In this blog we will checkout logging in rust. We will be building a logger interface from scratch using the logs module in rust and also go through why it is required.
Subhro Acharjee
11/15/20243 min read


What is logging?
Logging in software engineering is the process of recording actions or events that occur in a system. It’s like a diary for your software, helping to track what’s happening. We need logging to identify and fix problems, monitor system performance, and understand user behavior. It’s crucial for maintaining and improving the system’s quality and security.
Every big software systems from operating systems to google search has logging in built because it helps us to track and audit bugs and issues whenever there is a one.

Logging In Rust
Logging in rust, turns out to be much easier than i thought it would be tbh. Its not that i am saying it is simple to use or easy to understand, it is just much easier to understand with comparison to borrow checker. But i guess that is not a fair comparison, so what i will do in this blog is do a little side by side comparison with logging mechanism of other languages, such as nodejs and golang.
Obviously that is not be fair to rust at all, given rust is much more complex and robust ecosystem than nodejs, and golang but, I have learned logging from nodejs and golang itself, so i will explain it from my perspective. And i will explain like how that is different.
Logs module in Rust
Rust has this public crate which is quite powerful in itself, and as i have seen in my research most of the logging rust library is just an wrapper around this logs crate. As per it's official documentation it is a lightweight logging facade. So what is a logging facade, a logging facade is like a middleman in computer programming that helps your code talk to different logging systems. It makes it easier for you to switch between different systems, without having to change much of your original code. It needs to be initialised once during bootstrap of the application and after that in any part of the code we can use the different logging macros.
The issue is it cant be used without and implementation/wrapper. In order to produce log output executables have to use a logger implementation compatible with the facade. In my game engine I am using the env_logger implementation.
Differences in rust and Nodejs and golang.
Again i know its not a fare comparison, so keep your pitchfork in the barn, and just read.
Logging comes in two parts, one is adding messages to console, as an audit of application runtime and another is tracing individual function lifetimes.
In rust logging and tracing comes separately yet they are really compatible and easy to use. Does that mean i am using tracing, heck nooo, to much complex for me at this point of time. Maybe later but not now. But to the main point, if one needs to add tracing and benchmarks it's really simple to use them in rust. So is it hard in golang or nodejs. Well the answer is not as simple as saying 'yes' or 'no'.
Nodejs as we know it is a single threaded asynchronous language that works on event loop and golang on the other hand uses a virtual threads built into its executable which map to system threads and increases the thread performance alot. So logging in all these three systems are tbh, quite different, nodejs logs are basically function that uses worker threads (winston) and keep monitors the or whenever a logger function is called they are passed to that worker thread for processing so that main thread is not blocked, hence, it might be slower (sorry js FAM!).
Golang on the other hand, if you are using log library (in built one) it doesn't needs an initialisation for it's work and tbh its really concurrent safe. Also with the capability of adding the defer statements in golang its quite superior to winston as in winston if you need to add logs on entry and exit of functions you need to add your original function through an wrapper, where as in golang it's more straight forward, just do logs.info() on starting and a defer block with another logs.info for end.
Rust with comparison to both of them has similar feature to winston, ie it needs an intialization but at the same time it is thread safe (sort of). The executables always needs an implentation of log crate, and thats i see as the only downside to logs in golang (I AM SO SORRY RUST FAM!).
I guess thats it. I have also added a video where i am recorded myself, implementing logs in my game engine, it more or less gives you an idea of how i do my research. It might be helpful to some, some might find it kinda repulsive. So if you are from the later category, please feel free to let me know, personally or through email (sacharjeeofficial@gmail.com)
Thanks.
References
logs crate: https://docs.rs/log/latest/log/
logs package golang: https://pkg.go.dev/log
winston: https://www.npmjs.com/package/winston
