Index

lognestmonster / 000f5ab

A general-purpose single-header C logging library and parser for event-based logs. (Incomplete)

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
6712 Aug 2019 18:39e1e07abUpdate README.mdJosh Stockin111N

Blob @ lognestmonster / README.md

text/plain7643 bytesdownload raw
1<img src="/static/logo.png" height="200px"/>
2
3_Multilevel logging for advanced programs._
4
51. [lognestmonster](#lognestmonster)
62. [Library Class Structure](#library-class-structure)
7 1. [Semantics](#semantics)
83. [Serialization Format](#serialization-format)
9 1. [Events](#events)
10 2. [Statements](#statements)
11 1. [Verbosity Level Enumeration](#verbosity-level-enumeration)
12 3. [Example](#example)
134. [Temporary Data Saving](#temporary-data-saving)
145. [Copyright](#copyright)
15
16# lognestmonster
17
18## Library Class Structure
19This is subject to future change over security concerns regarding pointers and memory allocation.
20```
21class lognestmonster
22
23 enum VerbosityLevels {INFO, DEBUG, VERBOSE, VERYVERBOSE, WARNING, ERROR}
24
25 struct QueueConfig
26 char * out_dir // directory to output log files
27
28 virtual void * alloc(size_t size) // implementation defaults to cstd malloc()
29 virtual void free(void * block) // implementation defaults to cstd free()
30 virtual void * serialize(LogObject * obj) // implementation defaults to manual serialization of standard LogObject to allocated block
31 virtual bool write(void * serialized, size_t size, std::ostream stream, bool append) // implementation defaults to writing entire serialized block to stream
32 virtual int delete(char * file_name) // implementation defaults to cstd remove()
33
34 interface LogObject
35 Pushable * parent
36 char * temp_file
37 virtual bool save_temp()
38 virtual bool delete_temp()
39
40 interface Pushable
41 protected:
42 std::vector<LogObject *> pushed
43 public:
44 push(LogObject * obj)
45 push(int verbosity, char * tag, char * message) // implicitly creates a Statement and then pushes
46
47 class Queue : Pushable
48 public:
49 struct QueueConfig * _config
50 constructor (struct QueueConfig * config)
51 write() // serializes, writes, and clears pushed LogObjects
52 write(LogObject * obj) // implicit push(), then write()
53 write(int verbosity, char * tag, char * message) // implicit Statement creation, push(), then write()
54
55 class Event : LogObject, Pushable
56 public:
57 constructor (LogObject * obj) // implicit push()
58 constructor (int verbosity, char * tag, char * message) // implicit Statement creation, then push()
59
60 class Statement : LogObject
61 public:
62 int verbosity
63 int timestamp
64 std::string * tag
65 std::string * message
66 constructor (int verbosity, char * tag, char * message)
67```
68### Semantics
69A `Queue` handles data serialization and file writing to the main logtree file. Queue writing refers to sending serialized logtree data to the outstream. Queue pushing refers to adding an Event or Statement to the queue for future writing.
70
71An `Event` is a pushable list of statements or events, or the "nest". Event pushing refers to adding an Event or Statement to the parent's list.
72
73A `Statement` is the data-containing log item with a timestamp, verbosity level, tag/invoker, and message.
74
75In reference to data serialization, `parser` as used here is just a deserializer.
76
77## Serialization Format
78
79By default the library serializes log tree information in a special format. This can be overriden by any programmer that uses the library.
80
81### Events
82Open event with `0x2` and close with `0x3`. Statements or more events can be written inbetween these tags.
83```
840x2 // open event
85 // more events or statements
860x3 // close event
87```
88
89### Statements
90Open statement with `0x0` and close `0x1`.
91
921. 1 byte for an open statement tag
932. 1 byte for a predefined verbosity level enum
943. 4 bytes for an unsigned integer timestamp
954. 1 byte for the length of the tag string
965. 0-255 bytes for the tag string
976. 2 bytes for the length of the message string
987. 0-65535 bytes for the message string
998. 1 byte for a close statement tag
100
101```
1020x0
103 unsigned char verbosity
104 unsigned int timestamp
105 unsigned char tag_size
106 unsigned char[] tag
107 unsigned short message_size
108 unsigned char[] message
1090x1
110```
111A close statement tag is always needed in case the serializer method is overriden and provides extra data/metadata. If a close statement tag isn't written, a parser/deserializer won't be able to read a serialized logtree with extra data.
112
113#### Verbosity Level Enumeration
114The 6 verbosity level enums and their byte values are:
115```
116INFO = 0
117DEBUG = 1
118VERBOSE = 2
119VERYVERBOSE = 3
120WARNING = 4
121ERROR = 5
122```
123
124### Example
1251 statement inside one 1 event:
126```
1270x2 // open event 1
1280x0 // open statement 1
1291565561768752 // timestamp 4
1300 // verbosity 1
1314 // tag_size 1
132"INIT" // tag 4
1335 // message_size 2
134"HELLO" // message 5
1350x1 // close statement 1
1360x3 // close event 1
137 // 21 total bytes for this log tree
138```
139With the sample log tree used here, the raw byte file totals 21 bytes. In use, a parser/deserializer could take this file and create output similar to the following:
140```
141Log: sample.raw
142File size: 21 bytes
143Content: 1 statement
144
145v 1 ITEM
146 1565561768752 - INFO - INIT - HELLO
147```
148
149## Temporary Data Saving
150
151By the nature of a push-write logging library, there's a chance that some created Statements and Events might not be pushed and written before the program's exit, whether it hangs, crashes, throws a runtime exception, is SIGKILLed, or anything else. Seeing as the point of logging is to find and diagnose errors with ease, it'd be frustrating to lose critical last-second information like this. The solution: save temporary serialized data for every creation or change to Statements or Events. Every logtree that ends in a Statement will have its own temporary data file; when a Statement is pushed to an Event, the Statement's file will be deleted and replaced into the greater Event file. See the following example for how data is separated into files:
152
153```
154Queue queue;
155Event event;
156Statement state1;
157Statement state2;
158
159// Existing files:
160// statement1.raw
161// statement2.raw
162
163event.push(state1)
164
165// Existing files:
166// event.raw
167// statement2.raw
168
169queue.push(event)
170
171// Existing files:
172// event.raw
173// statement2.raw
174
175event.push(state2)
176
177// Existing files:
178// event.raw (all log items now exist inside the event, in the queue)
179
180queue.write()
181
182// Existing files:
183// log12345.raw (consists of 2 statements inside 1 event)
184```
185
186In reality, file names will likely contain timestamps, hashes, UUIDs, or some other form of identifiable metadata.
187
188## Copyright
189
190lognestmonster Copyright (c) 2019 Joshua 'joshuas3' Stockin under the [GNU General Public License v3](LICENSE).
191
192The following should be present in each file.
193```
194lognestmonster Copyright (c) 2019 Joshua 'joshuas3' Stockin
195<https://github.com/JoshuaS3/lognestmonster/>.
196
197
198This file is part of lognestmonster.
199
200lognestmonster is free software: you can redistribute it and/or modify
201it under the terms of the GNU General Public License as published by
202the Free Software Foundation, either version 3 of the License, or
203(at your option) any later version.
204
205lognestmonster is distributed in the hope that it will be useful,
206but WITHOUT ANY WARRANTY; without even the implied warranty of
207MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
208GNU General Public License for more details.
209
210You should have received a copy of the GNU General Public License
211along with lognestmonster. If not, see <https://www.gnu.org/licenses/>.
212```
213