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

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