MagickCore 7.0.10
log.c
Go to the documentation of this file.
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% L OOO GGGG %
7% L O O G %
8% L O O G GG %
9% L O O G G %
10% LLLLL OOO GGG %
11% %
12% %
13% Log ImageMagick Events %
14% %
15% Software Design %
16% Cristy %
17% September 2002 %
18% %
19% %
20% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% https://imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
42#include "wizard/studio.h"
43#include "wizard/blob.h"
44#include "wizard/client.h"
45#include "wizard/configure.h"
46#include "wizard/exception.h"
48#include "wizard/hashmap.h"
49#include "wizard/log.h"
50#include "wizard/memory_.h"
51#include "wizard/option.h"
52#include "wizard/semaphore.h"
53#include "wizard/string_.h"
55#include "wizard/thread_.h"
57#include "wizard/timer.h"
58#include "wizard/token.h"
59#include "wizard/utility.h"
61#include "wizard/version.h"
62#include "wizard/xml-tree.h"
64
65/*
66 Define declarations.
67*/
68#define LogFilename "log.xml"
69
70/*
71 Typedef declarations.
72*/
73typedef enum
74{
76 NoHandler = 0x0000,
78 StdoutHandler = 0x0002,
79 StderrHandler = 0x0004,
80 FileHandler = 0x0008,
81 DebugHandler = 0x0010,
82 EventHandler = 0x0020
84
85typedef struct _EventInfo
86{
87 char
89
93
94typedef struct _HandlerInfo
95{
96 const char
97 name[10];
98
102
104{
107
110
111 char
116
117 size_t
120
121 FILE
123
124 size_t
126
130
133
136
137 size_t
139};
140
141/*
142 Declare log map.
143*/
144static const HandlerInfo
146 {
147 { "console", ConsoleHandler },
148 { "debug", DebugHandler },
149 { "event", EventHandler },
150 { "file", FileHandler },
151 { "none", NoHandler },
152 { "stderr", StderrHandler },
153 { "stdout", StdoutHandler },
154 { "", UndefinedHandler },
155 { "", UndefinedHandler },
156 { "", UndefinedHandler },
157 { "", UndefinedHandler },
158 { "", UndefinedHandler },
159 { "", UndefinedHandler },
160 { "", UndefinedHandler },
161 { "", UndefinedHandler },
162 { "", UndefinedHandler },
163 { "", UndefinedHandler },
164 { "", UndefinedHandler },
165 { "", UndefinedHandler },
166 { "", UndefinedHandler },
167 { "", UndefinedHandler },
168 { "", UndefinedHandler },
169 { "", UndefinedHandler },
170 { "", UndefinedHandler },
171 { "", UndefinedHandler },
172 { "", UndefinedHandler },
173 { "", UndefinedHandler },
174 { "", UndefinedHandler },
175 { "", UndefinedHandler },
176 { "", UndefinedHandler },
177 { "", UndefinedHandler },
178 { "", UndefinedHandler }
179 };
180
181typedef struct _LogMapInfo
182{
183 const LogEventType
185
186 const LogHandlerType
188
189 const char
193
194/*
195 Static declarations.
196*/
197static const LogMapInfo
199 {
200 { NoEvents, ConsoleHandler, "Magick-%g.log",
201 "%t %r %u %v %d %c[%p]: %m/%f/%l/%d\\n %e" }
202 };
203
204static char
206
207static LinkedListInfo
209
210static SemaphoreInfo
212
213/*
214 Forward declarations.
215*/
216static LogHandlerType
217 ParseLogHandlers(const char *);
218
221 LoadLogCache(LinkedListInfo *,const char *,const char *,const size_t,
222 ExceptionInfo *);
223
224/*
225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226% %
227% %
228% %
229% A c q u i r e L o g C a c h e %
230% %
231% %
232% %
233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234%
235% AcquireLogCache() caches one or more log configurations which provides a
236% mapping between log attributes and log name.
237%
238% The format of the AcquireLogCache method is:
239%
240% LinkedListInfo *AcquireLogCache(const char *filename,
241% ExceptionInfo *exception)
242%
243% A description of each parameter follows:
244%
245% o filename: The log configuration filename.
246%
247% o exception: Return any errors or warnings in this structure.
248%
249*/
250static LinkedListInfo *AcquireLogCache(const char *filename,
251 ExceptionInfo *exception)
252{
253 const StringInfo
254 *option;
255
257 *log_cache,
258 *options;
259
260 ssize_t
261 i;
262
264 status;
265
266 /*
267 Load built-in log map.
268 */
270 if (log_cache == (LinkedListInfo *) NULL)
271 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s`");
272 /*
273 Load external log map.
274 */
275 status=WizardTrue;
276 options=GetConfigureOptions(filename,exception);
277 option=(const StringInfo *) GetNextValueInLinkedList(options);
278 while (option != (const StringInfo *) NULL)
279 {
280 status&=LoadLogCache(log_cache,(const char *) GetStringInfoDatum(option),
281 GetStringInfoPath(option),0,exception);
282 option=(const StringInfo *) GetNextValueInLinkedList(options);
283 }
284 /*
285 Load built-in log map.
286 */
287 options=DestroyConfigureOptions(options);
288 for (i=0; i < (ssize_t) (sizeof(LogMap)/sizeof(*LogMap)); i++)
289 {
290 LogInfo
291 *log_info;
292
293 const LogMapInfo
294 *p;
295
296 p=LogMap+i;
297 log_info=(LogInfo *) AcquireWizardMemory(sizeof(*log_info));
298 if (log_info == (LogInfo *) NULL)
299 {
301 "memory allocation failed `%s'",p->filename);
302 continue;
303 }
304 (void) memset(log_info,0,sizeof(*log_info));
305 log_info->path=ConstantString("[built-in]");
306 log_info->timer=AcquireTimerInfo();
307 log_info->event_mask=p->event_mask;
308 log_info->handler_mask=p->handler_mask;
309 log_info->filename=ConstantString(p->filename);
310 log_info->format=ConstantString(p->format);
311 log_info->signature=WizardSignature;
312 status&=AppendValueToLinkedList(log_cache,log_info);
313 if (status == WizardFalse)
315 "memory allocation failed `%s'",log_info->name);
316 }
317 return(log_cache);
318}
319
320/*
321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322% %
323% %
324% %
325% C l o s e W i z a r d L o g %
326% %
327% %
328% %
329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330%
331% CloseWizardLog() closes the Wizard log.
332%
333% The format of the CloseWizardLog method is:
334%
335% CloseWizardLog(void)
336%
337*/
339{
341 *exception;
342
343 LogInfo
344 *log_info;
345
347 return;
348 exception=AcquireExceptionInfo();
349 log_info=(LogInfo *) GetLogInfo("*",exception);
350 exception=DestroyExceptionInfo(exception);
352 if (log_info->file != (FILE *) NULL)
353 {
354 (void) fprintf(log_info->file,"</log>\n");
355 (void) fclose(log_info->file);
356 log_info->file=(FILE *) NULL;
357 }
359}
360
361/*
362%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363% %
364% %
365% %
366+ G e t L o g I n f o %
367% %
368% %
369% %
370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371%
372% GetLogInfo() searches the log list for the specified name and if found
373% returns attributes for that log.
374%
375% The format of the GetLogInfo method is:
376%
377% const LogInfo *GetLogInfo(const char *name,ExceptionInfo *exception)
378%
379% A description of each parameter follows:
380%
381% o name: The log name.
382%
383% o exception: Return any errors or warnings in this structure.
384%
385*/
386WizardExport const LogInfo *GetLogInfo(const char *name,
387 ExceptionInfo *exception)
388{
389 const LogInfo
390 *p;
391
392 assert(exception != (ExceptionInfo *) NULL);
393 if (IsLogCacheInstantiated(exception) == WizardFalse)
394 return((const LogInfo *) NULL);
395 /*
396 Search for named log.
397 */
401 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
402 {
404 return(p);
405 }
406 while (p != (const LogInfo *) NULL)
407 {
408 if (LocaleCompare(name,p->name) == 0)
409 break;
411 }
412 if (p == (LogInfo *) NULL)
414 "no such element `%s'",name);
415 else
419 return(p);
420}
421
422/*
423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424% %
425% %
426% %
427% G e t L o g I n f o L i s t %
428% %
429% %
430% %
431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432%
433% GetLogInfoList() returns any logs that match the specified pattern.
434%
435% The format of the GetLogInfoList function is:
436%
437% const LogInfo **GetLogInfoList(const char *pattern,
438% size_t *number_preferences,ExceptionInfo *exception)
439%
440% A description of each parameter follows:
441%
442% o pattern: Specifies a pointer to a text string containing a pattern.
443%
444% o number_preferences: This integer returns the number of logs in the list.
445%
446% o exception: Return any errors or warnings in this structure.
447%
448*/
449#if defined(__cplusplus) || defined(c_plusplus)
450extern "C" {
451#endif
452
453static int LogInfoCompare(const void *x,const void *y)
454{
455 const LogInfo
456 **p,
457 **q;
458
459 p=(const LogInfo **) x,
460 q=(const LogInfo **) y;
461 if (LocaleCompare((*p)->path,(*q)->path) == 0)
462 return(LocaleCompare((*p)->name,(*q)->name));
463 return(LocaleCompare((*p)->path,(*q)->path));
464}
465
466#if defined(__cplusplus) || defined(c_plusplus)
467}
468#endif
469
470WizardExport const LogInfo **GetLogInfoList(const char *pattern,
471 size_t *number_preferences,ExceptionInfo *exception)
472{
473 const LogInfo
474 **preferences;
475
476 const LogInfo
477 *p;
478
479 ssize_t
480 i;
481
482 /*
483 Allocate log list.
484 */
485 assert(pattern != (char *) NULL);
486 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",pattern);
487 assert(number_preferences != (size_t *) NULL);
488 *number_preferences=0;
489 p=GetLogInfo("*",exception);
490 if (p == (const LogInfo *) NULL)
491 return((const LogInfo **) NULL);
492 preferences=(const LogInfo **) AcquireQuantumMemory((size_t)
493 GetNumberOfElementsInLinkedList(log_cache)+1UL,sizeof(*preferences));
494 if (preferences == (const LogInfo **) NULL)
495 return((const LogInfo **) NULL);
496 /*
497 Generate log list.
498 */
502 for (i=0; p != (const LogInfo *) NULL; )
503 {
504 if ((p->stealth == WizardFalse) &&
506 preferences[i++]=p;
508 }
510 qsort((void *) preferences,(size_t) i,sizeof(*preferences),LogInfoCompare);
511 preferences[i]=(LogInfo *) NULL;
512 *number_preferences=(size_t) i;
513 return(preferences);
514}
515
516/*
517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518% %
519% %
520% %
521% G e t L o g L i s t %
522% %
523% %
524% %
525%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
526%
527% GetLogList() returns any logs that match the specified pattern.
528%
529% The format of the GetLogList function is:
530%
531% char **GetLogList(const char *pattern,size_t *number_preferences,
532% ExceptionInfo *exception)
533%
534% A description of each parameter follows:
535%
536% o pattern: Specifies a pointer to a text string containing a pattern.
537%
538% o number_preferences: This integer returns the number of logs in the list.
539%
540% o exception: Return any errors or warnings in this structure.
541%
542*/
543
544#if defined(__cplusplus) || defined(c_plusplus)
545extern "C" {
546#endif
547
548static int LogCompare(const void *x,const void *y)
549{
550 const char
551 **p,
552 **q;
553
554 p=(const char **) x;
555 q=(const char **) y;
556 return(LocaleCompare(*p,*q));
557}
558
559#if defined(__cplusplus) || defined(c_plusplus)
560}
561#endif
562
563WizardExport char **GetLogList(const char *pattern,
564 size_t *number_preferences,ExceptionInfo *exception)
565{
566 char
567 **preferences;
568
569 const LogInfo
570 *p;
571
572 ssize_t
573 i;
574
575 /*
576 Allocate log list.
577 */
578 assert(pattern != (char *) NULL);
579 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",pattern);
580 assert(number_preferences != (size_t *) NULL);
581 *number_preferences=0;
582 p=GetLogInfo("*",exception);
583 if (p == (const LogInfo *) NULL)
584 return((char **) NULL);
585 preferences=(char **) AcquireQuantumMemory((size_t)
586 GetNumberOfElementsInLinkedList(log_cache)+1UL,sizeof(*preferences));
587 if (preferences == (char **) NULL)
588 return((char **) NULL);
589 /*
590 Generate log list.
591 */
595 for (i=0; p != (const LogInfo *) NULL; )
596 {
597 if ((p->stealth == WizardFalse) &&
599 preferences[i++]=ConstantString(p->name);
601 }
603 qsort((void *) preferences,(size_t) i,sizeof(*preferences),LogCompare);
604 preferences[i]=(char *) NULL;
605 *number_preferences=(size_t) i;
606 return(preferences);
607}
608
609/*
610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611% %
612% %
613% %
614% G e t L o g N a m e %
615% %
616% %
617% %
618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619%
620% GetLogName() returns the current log name.
621%
622% The format of the GetLogName method is:
623%
624% const char *GetLogName(void)
625%
626*/
627WizardExport const char *GetLogName(void)
628{
629 return(log_name);
630}
631
632/*
633%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634% %
635% %
636% %
637+ I s L o g L i s t I n s t a n t i a t e d %
638% %
639% %
640% %
641%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
642%
643% IsLogCacheInstantiated() determines if the log list is instantiated. If not,
644% it instantiates the list and returns it.
645%
646% The format of the IsLogInstantiated method is:
647%
648% WizardBooleanType IsLogCacheInstantiated(ExceptionInfo *exception)
649%
650% A description of each parameter follows.
651%
652% o exception: Return any errors or warnings in this structure.
653%
654*/
656{
657 if (log_cache == (LinkedListInfo *) NULL)
658 {
659 if (log_semaphore == (SemaphoreInfo *) NULL)
662 if (log_cache == (LinkedListInfo *) NULL)
665 }
666 return(log_cache != (LinkedListInfo *) NULL ? WizardTrue : WizardFalse);
667}
668
669/*
670%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671% %
672% %
673% %
674% I s E v e n t L o g g i n g %
675% %
676% %
677% %
678%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679%
680% IsEventLogging() returns WizardTrue if debug of events is enabled otherwise
681% WizardFalse.
682%
683% The format of the IsEventLogging method is:
684%
685% WizardBooleanType IsEventLogging(void)
686%
687*/
689{
690 const LogInfo
691 *log_info;
692
694 *exception;
695
696 if ((log_cache == (LinkedListInfo *) NULL) ||
698 return(WizardFalse);
699 exception=AcquireExceptionInfo();
700 log_info=GetLogInfo("*",exception);
701 exception=DestroyExceptionInfo(exception);
702 return(log_info->event_mask != NoEvents ? WizardTrue : WizardFalse);
703}
704/*
705%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706% %
707% %
708% %
709% L i s t L o g I n f o %
710% %
711% %
712% %
713%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714%
715% ListLogInfo() lists the log info to a file.
716%
717% The format of the ListLogInfo method is:
718%
719% WizardBooleanType ListLogInfo(FILE *file,ExceptionInfo *exception)
720%
721% A description of each parameter follows.
722%
723% o file: An pointer to a FILE.
724%
725% o exception: Return any errors or warnings in this structure.
726%
727*/
729{
730#define MegabytesToBytes(value) ((WizardSizeType) (value)*1024*1024)
731
732 const char
733 *path;
734
735 const LogInfo
736 **log_info;
737
738 ssize_t
739 j;
740
741 ssize_t
742 i;
743
744 size_t
745 number_aliases;
746
747 if (file == (const FILE *) NULL)
748 file=stdout;
749 log_info=GetLogInfoList("*",&number_aliases,exception);
750 if (log_info == (const LogInfo **) NULL)
751 return(WizardFalse);
752 j=0;
753 path=(const char *) NULL;
754 for (i=0; i < (ssize_t) number_aliases; i++)
755 {
756 if (log_info[i]->stealth != WizardFalse)
757 continue;
758 if ((path == (const char *) NULL) ||
759 (LocaleCompare(path,log_info[i]->path) != 0))
760 {
761 size_t
762 length;
763
764 if (log_info[i]->path != (char *) NULL)
765 (void) fprintf(file,"\nPath: %s\n\n",log_info[i]->path);
766 length=0;
767 for (j=0; j < (ssize_t) (8*sizeof(LogHandlerType)); j++)
768 {
769 size_t
770 mask;
771
772 if (*LogHandlers[j].name == '\0')
773 break;
774 mask=1;
775 mask<<=j;
776 if ((log_info[i]->handler_mask & mask) != 0)
777 {
778 (void) fprintf(file,"%s ",LogHandlers[j].name);
779 length+=strlen(LogHandlers[j].name);
780 }
781 }
782 for (j=(ssize_t) length; j <= 12; j++)
783 (void) FormatLocaleFile(file," ");
784 (void) fprintf(file," Generations Limit Format\n");
785 (void) fprintf(file,"-----------------------------------------"
786 "--------------------------------------\n");
787 }
788 path=log_info[i]->path;
789 if (log_info[i]->filename != (char *) NULL)
790 {
791 (void) fprintf(file,"%s",log_info[i]->filename);
792 for (j=(ssize_t) strlen(log_info[i]->filename); j <= 16; j++)
793 (void) fprintf(file," ");
794 }
795 (void) fprintf(file,"%9g ",(double) log_info[i]->generations);
796 (void) fprintf(file,"%8g ",(double) log_info[i]->limit);
797 if (log_info[i]->format != (char *) NULL)
798 (void) fprintf(file,"%s",log_info[i]->format);
799 (void) fprintf(file,"\n");
800 }
801 (void) fflush(file);
802 log_info=(const LogInfo **) RelinquishWizardMemory((void *) log_info);
803 return(WizardTrue);
804}
805
806/*
807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
808% %
809% %
810% %
811+ L o g C o m p o n e n t G e n e s i s %
812% %
813% %
814% %
815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816%
817% LogComponentGenesis() instantiates the log component.
818%
819% The format of the LogComponentGenesis method is:
820%
821% WizardBooleanType LogComponentGenesis(void)
822%
823*/
825{
827 *exception;
828
829 if (log_semaphore == (SemaphoreInfo *) NULL)
831 exception=AcquireExceptionInfo();
832 (void) GetLogInfo("*",exception);
833 exception=DestroyExceptionInfo(exception);
834 return(WizardTrue);
835}
836
837/*
838%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
839% %
840% %
841% %
842+ L o g C o m p o n e n t T e r m i n u s %
843% %
844% %
845% %
846%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
847%
848% LogComponentTerminus() destroys the log component.
849%
850% The format of the LogComponentTerminus method is:
851%
852% LogComponentTerminus(void)
853%
854*/
855
856static void *DestroyLogElement(void *log_info)
857{
858 LogInfo
859 *p;
860
861 p=(LogInfo *) log_info;
862 if (p->file != (FILE *) NULL)
863 {
864 (void) fprintf(p->file,"</log>\n");
865 (void) fclose(p->file);
866 p->file=(FILE *) NULL;
867 }
868 if (p->format != (char *) NULL)
870 if (p->filename != (char *) NULL)
872 if (p->path != (char *) NULL)
873 p->path=DestroyString(p->path);
874 if (p->timer != (TimerInfo *) NULL)
876 if (p->event_semaphore != (SemaphoreInfo *) NULL)
879 return((void *) NULL);
880}
881
883{
884 if (log_semaphore == (SemaphoreInfo *) NULL)
887 if (log_cache != (LinkedListInfo *) NULL)
891}
892
893/*
894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895% %
896% %
897% %
898% L o g W i z a r d E v e n t %
899% %
900% %
901% %
902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
903%
904% LogWizardEvent() logs an event as determined by the log configuration file.
905% If an error occurs, WizardFalse is returned otherwise WizardTrue.
906%
907% The format of the LogWizardEvent method is:
908%
909% WizardBooleanType LogWizardEvent(const LogEventType type,
910% const char *module,const char *function,const size_t line,
911% const char *format,...)
912%
913% A description of each parameter follows:
914%
915% o type: The event type.
916%
917% o filename: The source module filename.
918%
919% o function: The function name.
920%
921% o line: The line number of the source module.
922%
923% o format: The output format.
924%
925*/
927 const char *module,const char *function,const size_t line,
928 const char *domain,const char *event)
929{
930 char
931 *text;
932
933 double
934 elapsed_time,
935 user_time;
936
938 *exception;
939
940 LogInfo
941 *log_info;
942
943 char
944 *q;
945
946 const char
947 *p;
948
949 size_t
950 extent;
951
952 time_t
953 seconds;
954
955 exception=AcquireExceptionInfo();
956 log_info=(LogInfo *) GetLogInfo("*",exception);
957 exception=DestroyExceptionInfo(exception);
958 seconds=time((time_t *) NULL);
959 elapsed_time=GetElapsedTime(log_info->timer);
960 user_time=GetUserTime(log_info->timer);
961 text=AcquireString(event);
962 if (log_info->format == (char *) NULL)
963 return(text);
964 extent=strlen(event)+WizardPathExtent;
965 if (LocaleCompare(log_info->format,"xml") == 0)
966 {
967 char
968 timestamp[WizardPathExtent];
969
970 /*
971 Translate event in "XML" format.
972 */
973 (void) FormatWizardTime(seconds,extent,timestamp);
974 (void) FormatLocaleString(text,extent,
975 "<entry>\n"
976 " <timestamp>%s</timestamp>\n"
977 " <elapsed-time>%lu:%02lu.%06lu</elapsed-time>\n"
978 " <user-time>%0.3f</user-time>\n"
979 " <process-id>%.20g</process-id>\n"
980 " <thread-id>%.20g</thread-id>\n"
981 " <module>%s</module>\n"
982 " <function>%s</function>\n"
983 " <line>%.20g</line>\n"
984 " <domain>%s</domain>\n"
985 " <event>%s</event>\n"
986 "</entry>",timestamp,(unsigned long) (elapsed_time/60.0),(unsigned long)
987 floor(fmod(elapsed_time,60.0)),(unsigned long) (1000000.0*(elapsed_time-
988 floor(elapsed_time))+0.5),user_time,(double) getpid(),(double)
989 GetWizardThreadSignature(),module,function,(double) line,domain,event);
990 return(text);
991 }
992 /*
993 Translate event in "human readable" format.
994 */
995 q=text;
996 for (p=log_info->format; *p != '\0'; p++)
997 {
998 *q='\0';
999 if ((size_t) (q-text+WizardPathExtent) >= extent)
1000 {
1001 extent+=WizardPathExtent;
1002 text=(char *) ResizeQuantumMemory(text,extent+WizardPathExtent,
1003 sizeof(*text));
1004 if (text == (char *) NULL)
1005 return((char *) NULL);
1006 q=text+strlen(text);
1007 }
1008 /*
1009 The format of the log is defined by embedding special format characters:
1010
1011 %c client name
1012 %d domain
1013 %e event
1014 %f function
1015 %g generation
1016 %i thread id
1017 %l line
1018 %m module
1019 %n log name
1020 %p process id
1021 %r real CPU time
1022 %t wall clock time
1023 %u user CPU time
1024 %v version
1025 %% percent sign
1026 \n newline
1027 \r carriage return
1028 */
1029 if ((*p == '\\') && (*(p+1) == 'r'))
1030 {
1031 *q++='\r';
1032 p++;
1033 continue;
1034 }
1035 if ((*p == '\\') && (*(p+1) == 'n'))
1036 {
1037 *q++='\n';
1038 p++;
1039 continue;
1040 }
1041 if (*p != '%')
1042 {
1043 *q++=(*p);
1044 continue;
1045 }
1046 p++;
1047 if (*p == '\0')
1048 break;
1049 switch (*p)
1050 {
1051 case '\0':
1052 {
1053 p--;
1054 break;
1055 }
1056 case 'c':
1057 {
1058 q+=CopyWizardString(q,GetClientName(),extent);
1059 break;
1060 }
1061 case 'd':
1062 {
1063 q+=CopyWizardString(q,domain,extent);
1064 break;
1065 }
1066 case 'e':
1067 {
1068 q+=CopyWizardString(q,event,extent);
1069 break;
1070 }
1071 case 'f':
1072 {
1073 q+=CopyWizardString(q,function,extent);
1074 break;
1075 }
1076 case 'g':
1077 {
1078 if (log_info->generations == 0)
1079 {
1080 (void) CopyWizardString(q,"0",extent);
1081 q++;
1082 break;
1083 }
1084 q+=FormatLocaleString(q,extent,"%.20g",(double) (log_info->generation %
1085 log_info->generations));
1086 break;
1087 }
1088 case 'i':
1089 {
1090 q+=FormatLocaleString(q,extent,"%.20g",(double)
1092 break;
1093 }
1094 case 'l':
1095 {
1096 q+=FormatLocaleString(q,extent,"%.20g",(double) line);
1097 break;
1098 }
1099 case 'm':
1100 {
1101 const char
1102 *p;
1103
1104 for (p=module+strlen(module)-1; p > module; p--)
1105 if (*p == *DirectorySeparator)
1106 {
1107 p++;
1108 break;
1109 }
1110 q+=CopyWizardString(q,p,extent);
1111 break;
1112 }
1113 case 'n':
1114 {
1115 q+=CopyWizardString(q,GetLogName(),extent);
1116 break;
1117 }
1118 case 'p':
1119 {
1120 q+=FormatLocaleString(q,extent,"%.20g",(double) getpid());
1121 break;
1122 }
1123 case 'r':
1124 {
1125 q+=FormatLocaleString(q,extent,"%lu:%02lu.%03lu",(unsigned long)
1126 (elapsed_time/60.0),(unsigned long) floor(fmod(elapsed_time,60.0)),
1127 (unsigned long) (1000.0*(elapsed_time-floor(elapsed_time))+0.5));
1128 break;
1129 }
1130 case 't':
1131 {
1132 q+=FormatWizardTime(seconds,extent,q);
1133 break;
1134 }
1135 case 'u':
1136 {
1137 q+=FormatLocaleString(q,extent,"%0.3fu",user_time);
1138 break;
1139 }
1140 case 'v':
1141 {
1143 break;
1144 }
1145 case '%':
1146 {
1147 *q++=(*p);
1148 break;
1149 }
1150 default:
1151 {
1152 *q++='%';
1153 *q++=(*p);
1154 break;
1155 }
1156 }
1157 }
1158 *q='\0';
1159 return(text);
1160}
1161
1162static char *TranslateFilename(const LogInfo *log_info)
1163{
1164 char
1165 *filename;
1166
1167 char
1168 *q;
1169
1170 const char
1171 *p;
1172
1173 size_t
1174 extent;
1175
1176 /*
1177 Translate event in "human readable" format.
1178 */
1179 assert(log_info != (LogInfo *) NULL);
1180 assert(log_info->filename != (char *) NULL);
1181 filename=AcquireString((char *) NULL);
1182 extent=WizardPathExtent;
1183 q=filename;
1184 for (p=log_info->filename; *p != '\0'; p++)
1185 {
1186 *q='\0';
1187 if ((size_t) (q-filename+WizardPathExtent) >= extent)
1188 {
1189 extent+=WizardPathExtent;
1190 filename=(char *) ResizeQuantumMemory(filename,extent+WizardPathExtent,
1191 sizeof(*filename));
1192 if (filename == (char *) NULL)
1193 return((char *) NULL);
1194 q=filename+strlen(filename);
1195 }
1196 /*
1197 The format of the filename is defined by embedding special format
1198 characters:
1199
1200 %c client name
1201 %n log name
1202 %p process id
1203 %v version
1204 %% percent sign
1205 */
1206 if (*p != '%')
1207 {
1208 *q++=(*p);
1209 continue;
1210 }
1211 p++;
1212 if (*p == '\0')
1213 break;
1214 switch (*p)
1215 {
1216 case 'c':
1217 {
1218 q+=CopyWizardString(q,GetClientName(),extent);
1219 break;
1220 }
1221 case 'g':
1222 {
1223 if (log_info->generations == 0)
1224 {
1225 (void) CopyWizardString(q,"0",extent);
1226 q++;
1227 break;
1228 }
1229 q+=FormatLocaleString(q,extent,"%.20g",(double) (log_info->generation %
1230 log_info->generations));
1231 break;
1232 }
1233 case 'n':
1234 {
1235 q+=CopyWizardString(q,GetLogName(),extent);
1236 break;
1237 }
1238 case 'p':
1239 {
1240 q+=FormatLocaleString(q,extent,"%.20g",(double) getpid());
1241 break;
1242 }
1243 case 'v':
1244 {
1246 break;
1247 }
1248 case '%':
1249 {
1250 *q++=(*p);
1251 break;
1252 }
1253 default:
1254 {
1255 *q++='%';
1256 *q++=(*p);
1257 break;
1258 }
1259 }
1260 }
1261 *q='\0';
1262 return(filename);
1263}
1264
1266 const char *function,const size_t line,const char *format,
1267 va_list operands)
1268{
1269 char
1270 event[WizardPathExtent],
1271 *text;
1272
1273 const char
1274 *domain;
1275
1277 *exception;
1278
1279 int
1280 n;
1281
1282 LogInfo
1283 *log_info;
1284
1285 if (IsEventLogging() == WizardFalse)
1286 return(WizardFalse);
1287 exception=AcquireExceptionInfo();
1288 log_info=(LogInfo *) GetLogInfo("*",exception);
1289 exception=DestroyExceptionInfo(exception);
1290 if (log_info->event_semaphore == (SemaphoreInfo *) NULL)
1293 if ((log_info->event_mask & type) == 0)
1294 {
1296 return(WizardTrue);
1297 }
1299#if defined(WIZARDSTOOLKIT_HAVE_VSNPRINTF)
1300 n=vsnprintf(event,WizardPathExtent,format,operands);
1301#else
1302 n=vsprintf(event,format,operands);
1303#endif
1304 if (n < 0)
1305 event[WizardPathExtent-1]='\0';
1306 text=TranslateEvent(type,module,function,line,domain,event);
1307 if (text == (char *) NULL)
1308 {
1309 (void) ContinueTimer(log_info->timer);
1311 return(WizardFalse);
1312 }
1313 if ((log_info->handler_mask & ConsoleHandler) != 0)
1314 {
1315 (void) fprintf(stderr,"%s\n",text);
1316 (void) fflush(stderr);
1317 }
1318 if ((log_info->handler_mask & DebugHandler) != 0)
1319 {
1320#if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
1321 OutputDebugString(text);
1322 OutputDebugString("\n");
1323#endif
1324 }
1325 if ((log_info->handler_mask & EventHandler) != 0)
1326 {
1327#if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
1328 (void) NTReportEvent(text,WizardFalse);
1329#endif
1330 }
1331 if ((log_info->handler_mask & FileHandler) != 0)
1332 {
1333 struct stat
1334 file_info;
1335
1336 file_info.st_size=0;
1337 if (log_info->file != (FILE *) NULL)
1338 (void) fstat(fileno(log_info->file),&file_info);
1339 if (file_info.st_size > (WizardOffsetType) (1024*1024*log_info->limit))
1340 {
1341 (void) fprintf(log_info->file,"</log>\n");
1342 (void) fclose(log_info->file);
1343 log_info->file=(FILE *) NULL;
1344 }
1345 if (log_info->file == (FILE *) NULL)
1346 {
1347 char
1348 *filename;
1349
1350 filename=TranslateFilename(log_info);
1351 if (filename == (char *) NULL)
1352 {
1353 (void) ContinueTimer(log_info->timer);
1355 return(WizardFalse);
1356 }
1357 log_info->append=IsPathAcessible(filename);
1358 log_info->file=fopen_utf8(filename,"ab");
1359 filename=(char *) RelinquishWizardMemory(filename);
1360 if (log_info->file == (FILE *) NULL)
1361 {
1363 return(WizardFalse);
1364 }
1365 log_info->generation++;
1366 if (log_info->append == WizardFalse)
1367 (void) fprintf(log_info->file,"<?xml version=\"1.0\" "
1368 "encoding=\"UTF-8\" standalone=\"yes\"?>\n");
1369 (void) fprintf(log_info->file,"<log>\n");
1370 }
1371 (void) fprintf(log_info->file," <event>%s</event>\n",text);
1372 (void) fflush(log_info->file);
1373 }
1374 if ((log_info->handler_mask & StdoutHandler) != 0)
1375 {
1376 (void) fprintf(stdout,"%s\n",text);
1377 (void) fflush(stdout);
1378 }
1379 if ((log_info->handler_mask & StderrHandler) != 0)
1380 {
1381 (void) fprintf(stderr,"%s\n",text);
1382 (void) fflush(stderr);
1383 }
1384 text=(char *) RelinquishWizardMemory(text);
1385 (void) ContinueTimer(log_info->timer);
1387 return(WizardTrue);
1388}
1389
1390WizardBooleanType LogWizardEvent(const LogEventType type,const char *module,
1391 const char *function,const size_t line,const char *format,...)
1392{
1393 va_list
1394 operands;
1395
1397 status;
1398
1399 va_start(operands,format);
1400 status=LogWizardEventList(type,module,function,line,format,operands);
1401 va_end(operands);
1402 return(status);
1403}
1404
1405/*
1406%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1407% %
1408% %
1409% %
1410+ L o a d L o g L i s t %
1411% %
1412% %
1413% %
1414%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415%
1416% LoadLogCache() loads the log configurations which provides a mapping
1417% between log attributes and log name.
1418%
1419% The format of the LoadLogCache method is:
1420%
1421% WizardBooleanType LoadLogCache(LinkedListInfo *log_cache,const char *xml,
1422% const char *filename,const size_t depth,ExceptionInfo *exception)
1423%
1424% A description of each parameter follows:
1425%
1426% o xml: The log list in XML format.
1427%
1428% o filename: The log list filename.
1429%
1430% o depth: depth of <include /> statements.
1431%
1432% o exception: Return any errors or warnings in this structure.
1433%
1434*/
1436 const char *filename,const size_t depth,ExceptionInfo *exception)
1437{
1438 char
1439 keyword[WizardPathExtent],
1440 *token;
1441
1442 const char
1443 *q;
1444
1445 LogInfo
1446 *log_info = (LogInfo *) NULL;
1447
1448 size_t
1449 extent;
1450
1452 status;
1453
1454 /*
1455 Load the log map file.
1456 */
1457 if (xml == (const char *) NULL)
1458 return(WizardFalse);
1459 status=WizardTrue;
1460 token=AcquireString((char *) xml);
1461 extent=WizardPathExtent;
1462 for (q=(char *) xml; *q != '\0'; )
1463 {
1464 /*
1465 Interpret XML.
1466 */
1467 GetNextToken(q,&q,extent,token);
1468 if (*token == '\0')
1469 break;
1470 (void) CopyWizardString(keyword,token,WizardPathExtent);
1471 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1472 {
1473 /*
1474 Doctype element.
1475 */
1476 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1477 GetNextToken(q,&q,extent,token);
1478 continue;
1479 }
1480 if (LocaleNCompare(keyword,"<!--",4) == 0)
1481 {
1482 /*
1483 Comment element.
1484 */
1485 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1486 GetNextToken(q,&q,extent,token);
1487 continue;
1488 }
1489 if (LocaleCompare(keyword,"<include") == 0)
1490 {
1491 /*
1492 Include element.
1493 */
1494 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1495 {
1496 (void) CopyWizardString(keyword,token,WizardPathExtent);
1497 GetNextToken(q,&q,extent,token);
1498 if (*token != '=')
1499 continue;
1500 GetNextToken(q,&q,extent,token);
1501 if (LocaleCompare(keyword,"file") == 0)
1502 {
1503 if (depth > 200)
1504 (void) ThrowWizardException(exception,GetWizardModule(),
1505 ConfigureError,"include element nested too deeply: `%s'",
1506 token);
1507 else
1508 {
1509 char
1510 path[WizardPathExtent],
1511 *xml;
1512
1513 GetPathComponent(filename,HeadPath,path);
1514 if (*path != '\0')
1517 if (*token == *DirectorySeparator)
1518 (void) CopyWizardString(path,token,WizardPathExtent);
1519 else
1520 (void) ConcatenateWizardString(path,token,WizardPathExtent);
1521 xml=FileToXML(path,~0UL);
1522 if (xml != (char *) NULL)
1523 {
1524 status&=LoadLogCache(log_cache,xml,path,depth+1,
1525 exception);
1526 xml=DestroyString(xml);
1527 }
1528 }
1529 }
1530 }
1531 continue;
1532 }
1533 if (LocaleCompare(keyword,"<logmap>") == 0)
1534 {
1535 /*
1536 Allocate memory for the log list.
1537 */
1538 log_info=(LogInfo *) AcquireWizardMemory(sizeof(*log_info));
1539 if (log_info == (LogInfo *) NULL)
1541 "memory allocation failed: `%s'");
1542 (void) memset(log_info,0,sizeof(*log_info));
1543 log_info->path=ConstantString(filename);
1544 log_info->timer=AcquireTimerInfo();
1545 log_info->signature=WizardSignature;
1546 continue;
1547 }
1548 if (log_info == (LogInfo *) NULL)
1549 continue;
1550 if (LocaleCompare(keyword,"</logmap>") == 0)
1551 {
1552 status=AppendValueToLinkedList(log_cache,log_info);
1553 if (status == WizardFalse)
1554 (void) ThrowWizardException(exception,GetWizardModule(),
1555 ResourceError,"memory allocation failed: `%s'",filename);
1556 log_info=(LogInfo *) NULL;
1557 continue;
1558 }
1559 GetNextToken(q,(const char **) NULL,extent,token);
1560 if (*token != '=')
1561 continue;
1562 GetNextToken(q,&q,extent,token);
1563 GetNextToken(q,&q,extent,token);
1564 switch (*keyword)
1565 {
1566 case 'E':
1567 case 'e':
1568 {
1569 if (LocaleCompare((char *) keyword,"events") == 0)
1570 {
1571 log_info->event_mask=(LogEventType) (log_info->event_mask |
1573 break;
1574 }
1575 break;
1576 }
1577 case 'F':
1578 case 'f':
1579 {
1580 if (LocaleCompare((char *) keyword,"filename") == 0)
1581 {
1582 if (log_info->filename != (char *) NULL)
1583 log_info->filename=(char *) RelinquishWizardMemory(
1584 log_info->filename);
1585 log_info->filename=ConstantString(token);
1586 break;
1587 }
1588 if (LocaleCompare((char *) keyword,"format") == 0)
1589 {
1590 if (log_info->format != (char *) NULL)
1591 log_info->format=(char *) RelinquishWizardMemory(
1592 log_info->format);
1593 log_info->format=ConstantString(token);
1594 break;
1595 }
1596 break;
1597 }
1598 case 'G':
1599 case 'g':
1600 {
1601 if (LocaleCompare((char *) keyword,"generations") == 0)
1602 {
1603 if (LocaleCompare(token,"unlimited") == 0)
1604 {
1605 log_info->generations=(~0UL);
1606 break;
1607 }
1608 log_info->generations=StringToUnsignedLong(token);
1609 break;
1610 }
1611 break;
1612 }
1613 case 'L':
1614 case 'l':
1615 {
1616 if (LocaleCompare((char *) keyword,"limit") == 0)
1617 {
1618 if (LocaleCompare(token,"unlimited") == 0)
1619 {
1620 log_info->limit=(~0UL);
1621 break;
1622 }
1623 log_info->limit=StringToUnsignedLong(token);
1624 break;
1625 }
1626 break;
1627 }
1628 case 'O':
1629 case 'o':
1630 {
1631 if (LocaleCompare((char *) keyword,"output") == 0)
1632 {
1633 log_info->handler_mask=(LogHandlerType)
1634 (log_info->handler_mask | ParseLogHandlers(token));
1635 break;
1636 }
1637 break;
1638 }
1639 default:
1640 break;
1641 }
1642 }
1643 token=DestroyString(token);
1644 if (log_cache == (LinkedListInfo *) NULL)
1645 return(WizardFalse);
1646 return(status != 0 ? WizardTrue : WizardFalse);
1647}
1648
1649/*
1650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1651% %
1652% %
1653% %
1654+ P a r s e L o g H a n d l e r s %
1655% %
1656% %
1657% %
1658%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1659%
1660% ParseLogHandlers() parses a string defining which handlers takes a log
1661% message and exports them.
1662%
1663% The format of the ParseLogHandlers method is:
1664%
1665% LogHandlerType ParseLogHandlers(const char *handlers)
1666%
1667% A description of each parameter follows:
1668%
1669% o handlers: one or more handlers separated by commas.
1670%
1671*/
1672static LogHandlerType ParseLogHandlers(const char *handlers)
1673{
1675 handler_mask;
1676
1677 const char
1678 *p;
1679
1680 ssize_t
1681 i;
1682
1683 size_t
1684 length;
1685
1686 handler_mask=NoHandler;
1687 for (p=handlers; p != (char *) NULL; p=strchr(p,','))
1688 {
1689 while ((*p != '\0') && ((isspace((int) ((unsigned char) *p)) != 0) ||
1690 (*p == ',')))
1691 p++;
1692 for (i=0; *LogHandlers[i].name != '\0'; i++)
1693 {
1694 length=strlen(LogHandlers[i].name);
1695 if (LocaleNCompare(p,LogHandlers[i].name,length) == 0)
1696 {
1697 handler_mask=(LogHandlerType) (handler_mask | LogHandlers[i].handler);
1698 break;
1699 }
1700 }
1701 if (*LogHandlers[i].name == '\0')
1702 return(UndefinedHandler);
1703 }
1704 return(handler_mask);
1705}
1706
1707/*
1708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1709% %
1710% %
1711% %
1712% S e t L o g E v e n t M a s k %
1713% %
1714% %
1715% %
1716%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1717%
1718% SetLogEventMask() accepts a list that determines which events to log. All
1719% other events are ignored. By default, no debug is enabled. This method
1720% returns the previous log event mask.
1721%
1722% The format of the SetLogEventMask method is:
1723%
1724% LogEventType SetLogEventMask(const char *events)
1725%
1726% A description of each parameter follows:
1727%
1728% o events: log these events.
1729%
1730*/
1732{
1734 *exception;
1735
1736 LogInfo
1737 *log_info;
1738
1739 ssize_t
1740 option;
1741
1742 exception=AcquireExceptionInfo();
1743 log_info=(LogInfo *) GetLogInfo("*",exception);
1744 exception=DestroyExceptionInfo(exception);
1748 log_info->event_mask=(LogEventType) option;
1749 if (option == -1)
1750 log_info->event_mask=UndefinedEvents;
1752 return(log_info->event_mask);
1753}
1754
1755/*
1756%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1757% %
1758% %
1759% %
1760% S e t L o g F o r m a t %
1761% %
1762% %
1763% %
1764%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1765%
1766% SetLogFormat() sets the format for the "human readable" log record.
1767%
1768% The format of the LogWizardFormat method is:
1769%
1770% SetLogFormat(const char *format)
1771%
1772% A description of each parameter follows:
1773%
1774% o format: The log record format.
1775%
1776*/
1777WizardExport void SetLogFormat(const char *format)
1778{
1780 *exception;
1781
1782 LogInfo
1783 *log_info;
1784
1785 exception=AcquireExceptionInfo();
1786 log_info=(LogInfo *) GetLogInfo("*",exception);
1787 exception=DestroyExceptionInfo(exception);
1789 if (log_info->format != (char *) NULL)
1790 log_info->format=DestroyString(log_info->format);
1791 log_info->format=ConstantString(format);
1793}
1794
1795/*
1796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1797% %
1798% %
1799% %
1800% S e t L o g N a m e %
1801% %
1802% %
1803% %
1804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1805%
1806% SetLogName() sets the log name and returns it.
1807%
1808% The format of the SetLogName method is:
1809%
1810% const char *SetLogName(const char *name)
1811%
1812% A description of each parameter follows:
1813%
1814% o log_name: SetLogName() returns the current client name.
1815%
1816% o name: Specifies the new client name.
1817%
1818*/
1819WizardExport const char *SetLogName(const char *name)
1820{
1821 if ((name != (char *) NULL) && (*name != '\0'))
1823 return(log_name);
1824}
WizardExport const char * GetClientName(void)
Definition client.c:64
WizardExport LinkedListInfo * DestroyConfigureOptions(LinkedListInfo *options)
Definition configure.c:298
WizardExport LinkedListInfo * GetConfigureOptions(const char *filename, ExceptionInfo *exception)
Definition configure.c:585
#define ThrowFatalException(severity, tag)
WizardExport ExceptionInfo * AcquireExceptionInfo(void)
Definition exception.c:125
WizardExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition exception.c:399
WizardExport WizardBooleanType ThrowWizardException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *format,...)
Definition exception.c:1029
@ OptionWarning
Definition exception.h:63
@ ResourceFatalError
Definition exception.h:121
@ ConfigureError
Definition exception.h:88
@ ResourceError
Definition exception.h:101
WizardExport void * GetValueFromLinkedList(LinkedListInfo *list_info, const size_t index)
Definition hashmap.c:787
WizardExport WizardBooleanType IsLinkedListEmpty(const LinkedListInfo *list_info)
Definition hashmap.c:1206
WizardExport void ResetLinkedListIterator(LinkedListInfo *list_info)
Definition hashmap.c:1919
WizardExport size_t GetNumberOfElementsInLinkedList(const LinkedListInfo *list_info)
Definition hashmap.c:678
WizardExport WizardBooleanType AppendValueToLinkedList(LinkedListInfo *list_info, const void *value)
Definition hashmap.c:149
WizardExport WizardBooleanType InsertValueInLinkedList(LinkedListInfo *list_info, const size_t index, const void *value)
Definition hashmap.c:991
WizardExport void * RemoveElementByValueFromLinkedList(LinkedListInfo *list_info, const void *value)
Definition hashmap.c:1595
WizardExport LinkedListInfo * NewLinkedList(const size_t capacity)
Definition hashmap.c:1362
WizardExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition hashmap.c:605
WizardExport LinkedListInfo * DestroyLinkedList(LinkedListInfo *list_info, void *(*relinquish_value)(void *))
Definition hashmap.c:397
WizardExport ssize_t FormatLocaleFile(FILE *file, const char *format,...)
Definition locale.c:371
WizardExport ssize_t FormatLocaleString(char *string, const size_t length, const char *format,...)
Definition locale.c:465
WizardExport const LogInfo ** GetLogInfoList(const char *pattern, size_t *number_preferences, ExceptionInfo *exception)
Definition log.c:470
WizardBooleanType LogWizardEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition log.c:1390
WizardExport WizardBooleanType LogComponentGenesis(void)
Definition log.c:824
WizardExport char ** GetLogList(const char *pattern, size_t *number_preferences, ExceptionInfo *exception)
Definition log.c:563
static char * TranslateEvent(const LogEventType wizard_unused(type), const char *module, const char *function, const size_t line, const char *domain, const char *event)
Definition log.c:926
WizardExport LogEventType SetLogEventMask(const char *events)
Definition log.c:1731
WizardExport const char * GetLogName(void)
Definition log.c:627
static LinkedListInfo * AcquireLogCache(const char *filename, ExceptionInfo *exception)
Definition log.c:250
WizardBooleanType LogWizardEventList(const LogEventType type, const char *module, const char *function, const size_t line, const char *format, va_list operands)
Definition log.c:1265
static const LogMapInfo LogMap[]
Definition log.c:198
WizardExport void LogComponentTerminus(void)
Definition log.c:882
LogHandlerType
Definition log.c:74
@ DebugHandler
Definition log.c:81
@ ConsoleHandler
Definition log.c:77
@ NoHandler
Definition log.c:76
@ FileHandler
Definition log.c:80
@ UndefinedHandler
Definition log.c:75
@ EventHandler
Definition log.c:82
@ StderrHandler
Definition log.c:79
@ StdoutHandler
Definition log.c:78
static LogHandlerType ParseLogHandlers(const char *)
Definition log.c:1672
static const HandlerInfo LogHandlers[32]
Definition log.c:145
WizardExport WizardBooleanType ListLogInfo(FILE *file, ExceptionInfo *exception)
Definition log.c:728
WizardExport const char * SetLogName(const char *name)
Definition log.c:1819
static int LogInfoCompare(const void *x, const void *y)
Definition log.c:453
static SemaphoreInfo * log_semaphore
Definition log.c:211
WizardExport void SetLogFormat(const char *format)
Definition log.c:1777
WizardExport WizardBooleanType IsEventLogging(void)
Definition log.c:688
WizardExport void CloseWizardLog(void)
Definition log.c:338
struct _LogMapInfo LogMapInfo
static int LogCompare(const void *x, const void *y)
Definition log.c:548
static char * TranslateFilename(const LogInfo *log_info)
Definition log.c:1162
struct _HandlerInfo HandlerInfo
static void * DestroyLogElement(void *log_info)
Definition log.c:856
static char log_name[WizardPathExtent]
Definition log.c:205
struct _EventInfo EventInfo
static WizardBooleanType LoadLogCache(LinkedListInfo *, const char *, const char *, const size_t, ExceptionInfo *)
Definition log.c:1435
static WizardBooleanType IsLogCacheInstantiated(ExceptionInfo *)
Definition log.c:655
WizardExport const LogInfo * GetLogInfo(const char *name, ExceptionInfo *exception)
Definition log.c:386
#define LogFilename
Definition log.c:68
static LinkedListInfo * log_cache
Definition log.c:208
LogEventType
Definition log.h:36
@ NoEvents
Definition log.h:38
@ TraceEvent
Definition log.h:39
@ UndefinedEvents
Definition log.h:37
#define GetWizardModule()
Definition log.h:30
WizardExport void * AcquireWizardMemory(const size_t size)
Definition memory.c:586
WizardExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition memory.c:657
WizardExport void * RelinquishWizardMemory(void *memory)
Definition memory.c:1039
WizardExport void * ResizeQuantumMemory(void *memory, const size_t count, const size_t quantum)
Definition memory.c:1236
#define WizardExport
#define WizardPathExtent
#define WizardSignature
#define wizard_unused(x)
WizardExport ssize_t ParseWizardOption(const WizardOption option, const WizardBooleanType list, const char *options)
Definition option.c:422
WizardExport const char * WizardOptionToMnemonic(const WizardOption option, const ssize_t type)
Definition option.c:531
@ WizardLogEventOptions
Definition option.h:52
WizardExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition semaphore.c:338
WizardExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition semaphore.c:156
WizardExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:282
WizardExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:437
WizardExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition semaphore.c:247
static unsigned long StringToUnsignedLong(const char *value)
WizardExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition string.c:1608
WizardExport char * DestroyString(char *string)
Definition string.c:830
WizardExport int LocaleCompare(const char *p, const char *q)
Definition string.c:1510
WizardExport char * ConstantString(const char *source)
Definition string.c:655
WizardExport size_t ConcatenateWizardString(char *destination, const char *source, const size_t length)
Definition string.c:478
WizardExport char * AcquireString(const char *source)
Definition string.c:133
WizardExport ssize_t FormatWizardTime(const time_t time, const size_t length, char *timestamp)
Definition string.c:1105
WizardExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition string.c:1251
WizardExport size_t CopyWizardString(char *destination, const char *source, const size_t length)
Definition string.c:762
WizardExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition string.c:1309
LogEventType event
Definition log.c:91
char * name
Definition log.c:88
LogHandlerType handler
Definition log.c:100
const char name[10]
Definition log.c:97
char * filename
Definition log.c:114
SemaphoreInfo * event_semaphore
Definition log.c:135
WizardBooleanType stealth
Definition log.c:129
size_t limit
Definition log.c:119
char * name
Definition log.c:113
char * format
Definition log.c:115
size_t signature
Definition log.c:138
WizardBooleanType append
Definition log.c:128
TimerInfo * timer
Definition log.c:132
size_t generations
Definition log.c:118
LogEventType event_mask
Definition log.c:106
size_t generation
Definition log.c:125
char * path
Definition log.c:112
LogHandlerType handler_mask
Definition log.c:109
FILE * file
Definition log.c:122
const char * filename
Definition log.c:190
const LogEventType event_mask
Definition log.c:184
const LogHandlerType handler_mask
Definition log.c:187
const char * format
Definition log.c:191
#define DirectorySeparator
Definition studio.h:239
static size_t GetWizardThreadSignature(void)
WizardExport double GetUserTime(TimerInfo *timer_info)
Definition timer.c:312
WizardExport WizardBooleanType ContinueTimer(TimerInfo *timer_info)
Definition timer.c:138
WizardExport TimerInfo * DestroyTimerInfo(TimerInfo *timer_info)
Definition timer.c:176
WizardExport double GetElapsedTime(TimerInfo *timer_info)
Definition timer.c:244
WizardExport TimerInfo * AcquireTimerInfo(void)
Definition timer.c:101
WizardExport WizardBooleanType GlobExpression(const char *expression, const char *pattern, const WizardBooleanType case_insensitive)
Definition token.c:259
WizardExport void GetNextToken(const char *start, const char **end, const size_t extent, char *token)
Definition token.c:103
static FILE * fopen_utf8(const char *path, const char *mode)
WizardExport void GetPathComponent(const char *path, PathType type, char *component)
Definition utility.c:415
WizardExport WizardBooleanType IsPathAcessible(const char *path)
Definition utility.c:779
@ HeadPath
Definition utility.h:30
#define WizardLibVersionText
Definition version.h:31
ssize_t WizardOffsetType
Definition wizard-type.h:50
WizardBooleanType
Definition wizard-type.h:26
@ WizardTrue
Definition wizard-type.h:28
@ WizardFalse
Definition wizard-type.h:27
unsigned int WizardStatusType
Definition wizard-type.h:42
WizardPrivate char * FileToXML(const char *, const size_t)
Definition xml-tree.c:633