Hi,
Thpertic wrote:I'm coding atomically_log and I thought that for that source_ID should I create a table to store the name of the source? And then with severity what did you intend?
I'm mostly just throwing out ideas that could be used to make an OS better - the implementation details are entirely up to you.
For a full example; for the last version of my OS I got a little carried away. I started by wanting to be able to generate charts from the log (like the charts you get from
Bootchart for Linux, but at any point in time and not only during boot), which just meant recycling the time-stamps I already had to keep track of when different pieces of code start/stop running; but then I decided to add additional stuff to keep track of bytes read/written from IO devices (so I could create charts of disk and network bandwidth), and when CPUs change states (offline/online, and power management and power consumption) so that I could also create charts of CPU power consumption and how much power each piece of code consumed, and when each kernel API function is called (mostly for profiling the kernel), etc.
The end result was a set of events where each event has a header (entry size, entry type, source ID, timestamp and timestamp precision) followed by none or more bytes of data, where the "entry type" determined the type of data. Some of the event types were to assign a name to a source ID or device ID (where the data is a name string) or to cancel a previously assigned name (where the data is a 32-bit "termination status"). Some of the events were for device input or output where the data is a 32-bit "bytes sent/received".
"Generic events" were used if a process, CPU or device driver (on behalf of a device) wants to add a UTF-8 string to the log. For these the data is a 32-bit "event ID", an 8-bit "severity" and then the string itself. For the "event ID", if the highest bit is clear it's a standardised event ID defined by my event log specification (which only defined "Unspecified" but I wanted to make it easy for me to add more in the future) and if the highest bit is set then its meaning depends on the code that created it (mostly only useful for the person that wrote that code). The severity value was split into ranges like this:
- 0x00 to 0x3F = Informational, for debugging only
0x40 to 0x7F = Informational
0x80 to 0xBF = Error condition (that doesn't prevent future functionality)
0xC0 to 0xFF = Critical condition (that does prevent future functionality)
I also designed a method of "compaction". Specifically, the log itself exists in a fixed area of kernel space, and if/when that area gets full the kernel splits it into an "old half" and a "recent half", then (for events in the "old half" only) the kernel converts some kinds of events into their "historical" counterpart (e.g. if a process is still running, it's "assign name" event would be converted to a "historical assign name" event so that you could still figure out the name of the process) and all other events in the "old half" were deleted; and while this was happening all the events would be shifted ("compacted") so that all the free space (from deleted events) ends up at the end of the buffer. That way the log in memory was always self consistent (e.g. everything that refers to a "source ID" in the log would have an "assign name" event or a "historical assign name" event). This also meant that a service that continually pumps the kernel log to disk (by appending new events to a file) could set log file size limits (e.g. if the log file is larger than 10 MiB, start a new log file) and could include the historical events at the start of a new log file while not recording the historical events after a new log file is started; so that each individual log file would be self consistent too. Of course then you'd probably do a "log rotation" thing on top of that (e.g. maybe keep the most recent log files on disk, but delete log files from 100+ days ago so that after a few hundred years the hard drive doesn't get completely filled with old logs).
Note that what I do isn't necessarily what I'd recommend that a beginner does. The reason I'm describing this is because sometimes beginners don't really think about what they actually want (e.g. and end up just displaying ASCII during boot because they followed a "deliberately minimal to make it easier to understand" tutorial without thinking about it). In other words; I'm trying to encourage you to think about what you want for your OS (by describing a more complex/powerful alternative).
Cheers,
Brendan