Bugfixing
[tpg/acess2.git] / Kernel / logging.c
1 /*
2  * Acess 2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * logging.c - Kernel Logging Service
6  */
7 #include <acess.h>
8
9 #define PRINT_ON_APPEND 1
10
11 // === CONSTANTS ===
12 enum eLogLevels
13 {
14         LOG_LEVEL_KPANIC,
15         LOG_LEVEL_PANIC,
16         LOG_LEVEL_FATAL,
17         LOG_LEVEL_ERROR,
18         LOG_LEVEL_WARNING,
19         LOG_LEVEL_NOTICE,
20         LOG_LEVEL_LOG,
21         LOG_LEVEL_DEBUG,
22         NUM_LOG_LEVELS
23 };
24 const char      *csaLevelColours[] = {
25                 "\x1B[35m", "\x1B[34m", "\x1B[36m", "\x1B[31m",
26                 "\x1B[33m", "\x1B[32m", "\x1B[0m", "\x1B[0m"
27                 };
28 const char      *csaLevelCodes[] =  {"k","p","f","e","w","n","l","d"};
29
30 // === TYPES ===
31 typedef struct sLogEntry
32 {
33         struct sLogEntry        *Next;
34         struct sLogEntry        *LevelNext;
35         Sint64  Time;
36          int    Level;
37          int    Length;
38         char    Ident[9];
39         char    Data[];
40 }       tLogEntry;
41 typedef struct sLogList
42 {
43         tLogEntry       *Head;
44         tLogEntry       *Tail;
45 }       tLogList;
46
47 // === PROTOTYPES ===
48 void    Log_AddEvent(char *Ident, int Level, char *Format, va_list Args);
49 static void     Log_Int_PrintMessage(tLogEntry *Entry);
50 void    Log_KernelPanic(char *Ident, char *Message, ...);
51 void    Log_Panic(char *Ident, char *Message, ...);
52 void    Log_Error(char *Ident, char *Message, ...);
53 void    Log_Warning(char *Ident, char *Message, ...);
54 void    Log_Notice(char *Ident, char *Message, ...);
55 void    Log_Log(char *Ident, char *Message, ...);
56 void    Log_Debug(char *Ident, char *Message, ...);
57
58 // === EXPORTS ===
59 EXPORT(Log_Panic);
60 EXPORT(Log_Error);
61 EXPORT(Log_Warning);
62 EXPORT(Log_Notice);
63 EXPORT(Log_Log);
64 EXPORT(Log_Debug);
65
66 // === GLOBALS ===
67 tSpinlock       glLog;
68 tSpinlock       glLogOutput;
69 tLogList        gLog;
70 tLogList        gLog_Levels[NUM_LOG_LEVELS];
71
72 // === CODE ===
73 /**
74  * \brief Adds an event to the log
75  */
76 void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
77 {
78          int    len;
79         tLogEntry       *ent;
80         va_list args_tmp;
81         
82         if( Level >= NUM_LOG_LEVELS )   return;
83         
84         va_copy(args_tmp, Args);
85         len = vsnprintf(NULL, 256, Format, args_tmp);
86         
87         //Log("len = %i", len);
88         
89         ent = malloc(sizeof(tLogEntry)+len+1);
90         ent->Time = now();
91         strncpy(ent->Ident, Ident, 8);
92         ent->Level = Level;
93         ent->Length = len;
94         vsnprintf( ent->Data, 256, Format, Args );
95         
96         //Log("ent->Ident = '%s'", ent->Ident);
97         //Log("ent->Data = '%s'", ent->Data);
98         
99         LOCK( &glLog );
100         
101         ent->Next = gLog.Tail;
102         if(gLog.Head)
103                 gLog.Tail = ent;
104         else
105                 gLog.Tail = gLog.Head = ent;
106         
107         ent->LevelNext = gLog_Levels[Level].Tail;
108         if(gLog_Levels[Level].Head)
109                 gLog_Levels[Level].Tail = ent;
110         else
111                 gLog_Levels[Level].Tail = gLog_Levels[Level].Head = ent;
112         
113         RELEASE( &glLog );
114         
115         #if PRINT_ON_APPEND
116         Log_Int_PrintMessage( ent );
117         #endif
118         
119 }
120
121 /**
122  * \brief Prints a log message to the debug console
123  */
124 void Log_Int_PrintMessage(tLogEntry *Entry)
125 {
126         LogF("%s%018lli%s [%+8s] %s\x1B[0m\n",
127                 csaLevelColours[Entry->Level],
128                 Entry->Time,
129                 csaLevelCodes[Entry->Level],
130                 Entry->Ident,
131                 Entry->Data
132                 );
133 }
134
135 /**
136  * \brief KERNEL PANIC!!!!
137  */
138 void Log_KernelPanic(char *Ident, char *Message, ...)
139 {
140         va_list args;   
141         va_start(args, Message);
142         Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
143         va_end(args);
144 }
145
146 /**
147  * \brief Panic Message - Driver Unrecoverable error
148  */
149 void Log_Panic(char *Ident, char *Message, ...)
150 {
151         va_list args;   
152         va_start(args, Message);
153         Log_AddEvent(Ident, LOG_LEVEL_PANIC, Message, args);
154         va_end(args);
155 }
156
157 /**
158  * \brief Error Message - Recoverable Error
159  */
160 void Log_Error(char *Ident, char *Message, ...)
161 {
162         va_list args;   
163         va_start(args, Message);
164         Log_AddEvent(Ident, LOG_LEVEL_ERROR, Message, args);
165         va_end(args);
166 }
167
168 /**
169  * \brief Warning Message - Something the user should know
170  */
171 void Log_Warning(char *Ident, char *Message, ...)
172 {
173         va_list args;
174         
175         va_start(args, Message);
176         Log_AddEvent(Ident, LOG_LEVEL_WARNING, Message, args);
177         va_end(args);
178 }
179
180 /**
181  * \brief Notice Message - Something the user might like to know
182  */
183 void Log_Notice(char *Ident, char *Message, ...)
184 {
185         va_list args;   
186         va_start(args, Message);
187         Log_AddEvent(Ident, LOG_LEVEL_NOTICE, Message, args);
188         va_end(args);
189 }
190
191 /**
192  * \brief Log Message - Possibly useful information
193  */
194 void Log_Log(char *Ident, char *Message, ...)
195 {
196         va_list args;   
197         va_start(args, Message);
198         Log_AddEvent(Ident, LOG_LEVEL_LOG, Message, args);
199         va_end(args);
200 }
201
202 /**
203  * \brief Debug Message - Only a developer would want this info
204  */
205 void Log_Debug(char *Ident, char *Message, ...)
206 {
207         va_list args;   
208         va_start(args, Message);
209         Log_AddEvent(Ident, LOG_LEVEL_DEBUG, Message, args);
210         va_end(args);
211 }

UCC git Repository :: git.ucc.asn.au