42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/configure-private.h"
47 #include "MagickCore/exception.h"
48 #include "MagickCore/exception-private.h"
49 #include "MagickCore/linked-list.h"
50 #include "MagickCore/log.h"
51 #include "MagickCore/log-private.h"
52 #include "MagickCore/memory_.h"
53 #include "MagickCore/nt-base-private.h"
54 #include "MagickCore/option.h"
55 #include "MagickCore/semaphore.h"
56 #include "MagickCore/timer.h"
57 #include "MagickCore/string_.h"
58 #include "MagickCore/string-private.h"
59 #include "MagickCore/thread_.h"
60 #include "MagickCore/thread-private.h"
61 #include "MagickCore/timer-private.h"
62 #include "MagickCore/token.h"
63 #include "MagickCore/utility.h"
64 #include "MagickCore/utility-private.h"
65 #include "MagickCore/version.h"
66 #include "MagickCore/xml-tree.h"
67 #include "MagickCore/xml-tree-private.h"
72 #define LogFilename "log.xml"
79 UndefinedHandler = 0x0000,
81 ConsoleHandler = 0x0001,
82 StdoutHandler = 0x0002,
83 StderrHandler = 0x0004,
85 DebugHandler = 0x0010,
86 EventHandler = 0x0020,
87 MethodHandler = 0x0040
168 {
"Console", ConsoleHandler },
169 {
"Debug", DebugHandler },
170 {
"Event", EventHandler },
171 {
"File", FileHandler },
172 {
"None", NoHandler },
173 {
"Stderr", StderrHandler },
174 {
"Stdout", StdoutHandler },
175 {
"", UndefinedHandler },
176 {
"", UndefinedHandler },
177 {
"", UndefinedHandler },
178 {
"", UndefinedHandler },
179 {
"", UndefinedHandler },
180 {
"", UndefinedHandler },
181 {
"", UndefinedHandler },
182 {
"", UndefinedHandler },
183 {
"", UndefinedHandler },
184 {
"", UndefinedHandler },
185 {
"", UndefinedHandler },
186 {
"", UndefinedHandler },
187 {
"", UndefinedHandler },
188 {
"", UndefinedHandler },
189 {
"", UndefinedHandler },
190 {
"", UndefinedHandler },
191 {
"", UndefinedHandler },
192 {
"", UndefinedHandler },
193 {
"", UndefinedHandler },
194 {
"", UndefinedHandler },
195 {
"", UndefinedHandler },
196 {
"", UndefinedHandler },
197 {
"", UndefinedHandler },
198 {
"", UndefinedHandler },
199 {
"", UndefinedHandler }
205 { NoEvents, ConsoleHandler,
"Magick-%g.log",
206 "%t %r %u %v %d %c[%p]: %m/%f/%l/%d\\n %e" }
210 log_name[MagickPathExtent] =
"Magick";
215 static MagickBooleanType
216 event_logging = MagickFalse;
224 #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
225 static LogHandlerType
226 ParseLogHandlers(
const char *) magick_attribute((__pure__));
232 static MagickBooleanType
233 IsLogCacheInstantiated(
ExceptionInfo *) magick_attribute((__pure__));
235 #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
236 static MagickBooleanType
237 LoadLogCache(
LinkedListInfo *,
const char *,
const char *,
const size_t,
282 cache=NewLinkedList(0);
284 #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
292 options=GetConfigureOptions(filename,exception);
293 option=(
const StringInfo *) GetNextValueInLinkedList(options);
296 status&=LoadLogCache(cache,(
const char *) GetStringInfoDatum(option),
297 GetStringInfoPath(option),0,exception);
298 option=(
const StringInfo *) GetNextValueInLinkedList(options);
300 options=DestroyConfigureOptions(options);
303 magick_unreferenced(filename);
308 for (i=0; i < (ssize_t) (
sizeof(LogMap)/
sizeof(*LogMap)); i++)
317 log_info=(
LogInfo *) AcquireMagickMemory(
sizeof(*log_info));
318 if (log_info == (
LogInfo *) NULL)
320 (void) ThrowMagickException(exception,GetMagickModule(),
321 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",p->filename);
324 (void) memset(log_info,0,
sizeof(*log_info));
325 log_info->path=ConstantString(
"[built-in]");
326 GetTimerInfo((
TimerInfo *) &log_info->timer);
327 log_info->event_mask=p->event_mask;
328 log_info->handler_mask=p->handler_mask;
329 log_info->filename=ConstantString(p->filename);
330 log_info->format=ConstantString(p->format);
331 log_info->signature=MagickCoreSignature;
332 status&=AppendValueToLinkedList(cache,log_info);
333 if (status == MagickFalse)
334 (void) ThrowMagickException(exception,GetMagickModule(),
335 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",log_info->name);
358 MagickExport
void CloseMagickLog(
void)
366 if (IsEventLogging() == MagickFalse)
368 exception=AcquireExceptionInfo();
369 log_info=GetLogInfo(
"*",exception);
370 exception=DestroyExceptionInfo(exception);
371 LockSemaphoreInfo(log_semaphore);
372 if (log_info->file != (FILE *) NULL)
374 (void) FormatLocaleFile(log_info->file,
"</log>\n");
375 (void) fclose(log_info->file);
376 log_info->file=(FILE *) NULL;
378 UnlockSemaphoreInfo(log_semaphore);
399 MagickExport LogEventType GetLogEventMask(
void)
407 exception=AcquireExceptionInfo();
408 log_info=GetLogInfo(
"*",exception);
409 exception=DestroyExceptionInfo(exception);
410 if (log_info == (
const LogInfo *) NULL)
412 return(log_info->event_mask);
446 if (IsLogCacheInstantiated(exception) == MagickFalse)
451 LockSemaphoreInfo(log_semaphore);
452 ResetLinkedListIterator(log_cache);
453 p=(
LogInfo *) GetNextValueInLinkedList(log_cache);
454 if ((name == (
const char *) NULL) || (LocaleCompare(name,
"*") == 0))
456 UnlockSemaphoreInfo(log_semaphore);
461 if (LocaleCompare(name,p->name) == 0)
463 p=(
LogInfo *) GetNextValueInLinkedList(log_cache);
466 (
void) InsertValueInLinkedList(log_cache,0,
467 RemoveElementByValueFromLinkedList(log_cache,p));
468 UnlockSemaphoreInfo(log_semaphore);
499 #if defined(__cplusplus) || defined(c_plusplus)
503 static int LogInfoCompare(
const void *x,
const void *y)
511 if (LocaleCompare((*p)->path,(*q)->path) == 0)
512 return(LocaleCompare((*p)->name,(*q)->name));
513 return(LocaleCompare((*p)->path,(*q)->path));
516 #if defined(__cplusplus) || defined(c_plusplus)
520 MagickExport
const LogInfo **GetLogInfoList(
const char *pattern,
535 assert(pattern != (
char *) NULL);
536 assert(number_preferences != (
size_t *) NULL);
537 if (IsEventLogging() != MagickFalse)
538 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
539 *number_preferences=0;
540 p=GetLogInfo(
"*",exception);
541 if (p == (
const LogInfo *) NULL)
542 return((
const LogInfo **) NULL);
543 preferences=(
const LogInfo **) AcquireQuantumMemory((
size_t)
544 GetNumberOfElementsInLinkedList(log_cache)+1UL,
sizeof(*preferences));
545 if (preferences == (
const LogInfo **) NULL)
546 return((
const LogInfo **) NULL);
550 LockSemaphoreInfo(log_semaphore);
551 ResetLinkedListIterator(log_cache);
552 p=(
const LogInfo *) GetNextValueInLinkedList(log_cache);
553 for (i=0; p != (
const LogInfo *) NULL; )
555 if ((p->stealth == MagickFalse) &&
556 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
558 p=(
const LogInfo *) GetNextValueInLinkedList(log_cache);
560 UnlockSemaphoreInfo(log_semaphore);
561 qsort((
void *) preferences,(
size_t) i,
sizeof(*preferences),LogInfoCompare);
562 preferences[i]=(
LogInfo *) NULL;
563 *number_preferences=(size_t) i;
595 #if defined(__cplusplus) || defined(c_plusplus)
599 static int LogCompare(
const void *x,
const void *y)
607 return(LocaleCompare(*p,*q));
610 #if defined(__cplusplus) || defined(c_plusplus)
614 MagickExport
char **GetLogList(
const char *pattern,
size_t *number_preferences,
629 assert(pattern != (
char *) NULL);
630 assert(number_preferences != (
size_t *) NULL);
631 if (IsEventLogging() != MagickFalse)
632 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
633 *number_preferences=0;
634 p=GetLogInfo(
"*",exception);
635 if (p == (
const LogInfo *) NULL)
636 return((
char **) NULL);
637 preferences=(
char **) AcquireQuantumMemory((
size_t)
638 GetNumberOfElementsInLinkedList(log_cache)+1UL,
sizeof(*preferences));
639 if (preferences == (
char **) NULL)
640 return((
char **) NULL);
644 LockSemaphoreInfo(log_semaphore);
645 ResetLinkedListIterator(log_cache);
646 p=(
const LogInfo *) GetNextValueInLinkedList(log_cache);
647 for (i=0; p != (
const LogInfo *) NULL; )
649 if ((p->stealth == MagickFalse) &&
650 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
651 preferences[i++]=ConstantString(p->name);
652 p=(
const LogInfo *) GetNextValueInLinkedList(log_cache);
654 UnlockSemaphoreInfo(log_semaphore);
655 qsort((
void *) preferences,(
size_t) i,
sizeof(*preferences),LogCompare);
656 preferences[i]=(
char *) NULL;
657 *number_preferences=(size_t) i;
679 MagickExport
const char *GetLogName(
void)
708 static inline void CheckEventLogging()
713 if (IsLinkedListEmpty(log_cache) != MagickFalse)
714 event_logging=MagickFalse;
720 ResetLinkedListIterator(log_cache);
721 p=(
LogInfo *) GetNextValueInLinkedList(log_cache);
722 event_logging=(p != (
LogInfo *) NULL) && (p->event_mask != NoEvents) ?
723 MagickTrue: MagickFalse;
727 static MagickBooleanType IsLogCacheInstantiated(
ExceptionInfo *exception)
732 ActivateSemaphoreInfo(&log_semaphore);
733 LockSemaphoreInfo(log_semaphore);
736 log_cache=AcquireLogCache(LogFilename,exception);
739 UnlockSemaphoreInfo(log_semaphore);
741 return(log_cache != (
LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
763 MagickExport MagickBooleanType IsEventLogging(
void)
765 return(event_logging);
792 MagickExport MagickBooleanType ListLogInfo(FILE *file,
ExceptionInfo *exception)
794 #define MegabytesToBytes(value) ((MagickSizeType) (value)*1024*1024)
811 if (file == (
const FILE *) NULL)
813 log_info=GetLogInfoList(
"*",&number_aliases,exception);
814 if (log_info == (
const LogInfo **) NULL)
817 path=(
const char *) NULL;
818 for (i=0; i < (ssize_t) number_aliases; i++)
820 if (log_info[i]->stealth != MagickFalse)
822 if ((path == (
const char *) NULL) ||
823 (LocaleCompare(path,log_info[i]->path) != 0))
828 if (log_info[i]->path != (
char *) NULL)
829 (
void) FormatLocaleFile(file,
"\nPath: %s\n\n",log_info[i]->path);
831 for (j=0; j < (ssize_t) (8*
sizeof(LogHandlerType)); j++)
836 if (*LogHandlers[j].name ==
'\0')
840 if ((log_info[i]->handler_mask & mask) != 0)
842 (void) FormatLocaleFile(file,
"%s ",LogHandlers[j].name);
843 length+=strlen(LogHandlers[j].name);
846 for (j=(ssize_t) length; j <= 12; j++)
847 (
void) FormatLocaleFile(file,
" ");
848 (void) FormatLocaleFile(file,
" Generations Limit Format\n");
849 (void) FormatLocaleFile(file,
"-----------------------------------------"
850 "--------------------------------------\n");
852 path=log_info[i]->path;
853 if (log_info[i]->filename != (
char *) NULL)
855 (void) FormatLocaleFile(file,
"%s",log_info[i]->filename);
856 for (j=(ssize_t) strlen(log_info[i]->filename); j <= 16; j++)
857 (
void) FormatLocaleFile(file,
" ");
859 (void) FormatLocaleFile(file,
"%9g ",(
double) log_info[i]->generations);
860 (void) FormatLocaleFile(file,
"%8g ",(
double) log_info[i]->limit);
861 if (log_info[i]->format != (
char *) NULL)
862 (
void) FormatLocaleFile(file,
"%s",log_info[i]->format);
863 (void) FormatLocaleFile(file,
"\n");
866 log_info=(
const LogInfo **) RelinquishMagickMemory((
void *) log_info);
870 #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
901 static MagickBooleanType LoadLogCache(
LinkedListInfo *cache,
const char *xml,
902 const char *filename,
const size_t depth,
ExceptionInfo *exception)
905 keyword[MagickPathExtent],
923 if (xml == (
const char *) NULL)
926 token=AcquireString(xml);
927 extent=strlen(token)+MagickPathExtent;
928 for (q=(
const char *) xml; *q !=
'\0'; )
933 (void) GetNextToken(q,&q,extent,token);
936 (void) CopyMagickString(keyword,token,MagickPathExtent);
937 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
942 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
943 (
void) GetNextToken(q,&q,extent,token);
946 if (LocaleNCompare(keyword,
"<!--",4) == 0)
951 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
952 (void) GetNextToken(q,&q,extent,token);
955 if (LocaleCompare(keyword,
"<include") == 0)
960 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
962 (void) CopyMagickString(keyword,token,MagickPathExtent);
963 (void) GetNextToken(q,&q,extent,token);
966 (void) GetNextToken(q,&q,extent,token);
967 if (LocaleCompare(keyword,
"file") == 0)
969 if (depth > MagickMaxRecursionDepth)
970 (void) ThrowMagickException(exception,GetMagickModule(),
971 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
975 path[MagickPathExtent],
978 GetPathComponent(filename,HeadPath,path);
980 (void) ConcatenateMagickString(path,DirectorySeparator,
982 if (*token == *DirectorySeparator)
983 (void) CopyMagickString(path,token,MagickPathExtent);
985 (
void) ConcatenateMagickString(path,token,MagickPathExtent);
986 file_xml=FileToXML(path,~0UL);
987 if (file_xml != (
char *) NULL)
989 status&=LoadLogCache(cache,file_xml,path,depth+1,
991 file_xml=DestroyString(file_xml);
998 if (LocaleCompare(keyword,
"<logmap>") == 0)
1003 log_info=(
LogInfo *) AcquireCriticalMemory(
sizeof(*log_info));
1004 (void) memset(log_info,0,
sizeof(*log_info));
1005 log_info->path=ConstantString(filename);
1006 GetTimerInfo((
TimerInfo *) &log_info->timer);
1007 log_info->signature=MagickCoreSignature;
1010 if (log_info == (
LogInfo *) NULL)
1012 if (LocaleCompare(keyword,
"</logmap>") == 0)
1014 status=AppendValueToLinkedList(cache,log_info);
1015 if (status == MagickFalse)
1016 (void) ThrowMagickException(exception,GetMagickModule(),
1017 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",filename);
1021 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1024 (void) GetNextToken(q,&q,extent,token);
1025 (void) GetNextToken(q,&q,extent,token);
1031 if (LocaleCompare((
char *) keyword,
"events") == 0)
1033 log_info->event_mask=(LogEventType) (log_info->event_mask |
1034 ParseCommandOption(MagickLogEventOptions,MagickTrue,token));
1042 if (LocaleCompare((
char *) keyword,
"filename") == 0)
1044 if (log_info->filename != (
char *) NULL)
1045 log_info->filename=(
char *)
1046 RelinquishMagickMemory(log_info->filename);
1047 log_info->filename=ConstantString(token);
1050 if (LocaleCompare((
char *) keyword,
"format") == 0)
1052 if (log_info->format != (
char *) NULL)
1053 log_info->format=(
char *)
1054 RelinquishMagickMemory(log_info->format);
1055 log_info->format=ConstantString(token);
1063 if (LocaleCompare((
char *) keyword,
"generations") == 0)
1065 if (LocaleCompare(token,
"unlimited") == 0)
1067 log_info->generations=(~0UL);
1070 log_info->generations=StringToUnsignedLong(token);
1078 if (LocaleCompare((
char *) keyword,
"limit") == 0)
1080 if (LocaleCompare(token,
"unlimited") == 0)
1082 log_info->limit=(~0UL);
1085 log_info->limit=StringToUnsignedLong(token);
1093 if (LocaleCompare((
char *) keyword,
"output") == 0)
1095 log_info->handler_mask=(LogHandlerType)
1096 (log_info->handler_mask | ParseLogHandlers(token));
1105 token=DestroyString(token);
1107 return(MagickFalse);
1108 return(status != 0 ? MagickTrue : MagickFalse);
1130 MagickPrivate MagickBooleanType LogComponentGenesis(
void)
1136 log_semaphore=AcquireSemaphoreInfo();
1137 exception=AcquireExceptionInfo();
1138 (void) GetLogInfo(
"*",exception);
1139 exception=DestroyExceptionInfo(exception);
1162 static void *DestroyLogElement(
void *log_info)
1168 if (p->file != (FILE *) NULL)
1170 (void) FormatLocaleFile(p->file,
"</log>\n");
1171 (void) fclose(p->file);
1172 p->file=(FILE *) NULL;
1174 if (p->format != (
char *) NULL)
1175 p->format=DestroyString(p->format);
1176 if (p->path != (
char *) NULL)
1177 p->path=DestroyString(p->path);
1178 if (p->filename != (
char *) NULL)
1179 p->filename=DestroyString(p->filename);
1181 RelinquishSemaphoreInfo(&p->event_semaphore);
1182 p=(
LogInfo *) RelinquishMagickMemory(p);
1183 return((
void *) NULL);
1186 MagickPrivate
void LogComponentTerminus(
void)
1189 ActivateSemaphoreInfo(&log_semaphore);
1190 LockSemaphoreInfo(log_semaphore);
1192 log_cache=DestroyLinkedList(log_cache,DestroyLogElement);
1193 event_logging=MagickFalse;
1194 UnlockSemaphoreInfo(log_semaphore);
1195 RelinquishSemaphoreInfo(&log_semaphore);
1232 static char *TranslateEvent(
const char *module,
const char *
function,
1233 const size_t line,
const char *domain,
const char *event)
1260 exception=AcquireExceptionInfo();
1261 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1262 exception=DestroyExceptionInfo(exception);
1263 seconds=GetMagickTime();
1264 elapsed_time=GetElapsedTime(&log_info->timer);
1265 user_time=GetUserTime(&log_info->timer);
1266 text=AcquireString(event);
1267 if (log_info->format == (
char *) NULL)
1269 extent=strlen(event)+MagickPathExtent;
1270 if (LocaleCompare(log_info->format,
"xml") == 0)
1273 timestamp[MagickTimeExtent];
1278 (void) FormatMagickTime(seconds,
sizeof(timestamp),timestamp);
1279 (void) FormatLocaleString(text,extent,
1281 " <timestamp>%s</timestamp>\n"
1282 " <elapsed-time>%lu:%02lu.%06lu</elapsed-time>\n"
1283 " <user-time>%0.3f</user-time>\n"
1284 " <process-id>%.20g</process-id>\n"
1285 " <thread-id>%.20g</thread-id>\n"
1286 " <module>%s</module>\n"
1287 " <function>%s</function>\n"
1288 " <line>%.20g</line>\n"
1289 " <domain>%s</domain>\n"
1290 " <event>%s</event>\n"
1291 "</entry>",timestamp,(
unsigned long) (elapsed_time/60.0),
1292 (
unsigned long) floor(fmod(elapsed_time,60.0)),(
unsigned long)
1293 (1000000.0*(elapsed_time-floor(elapsed_time))+0.5),user_time,
1294 (
double) getpid(),(double) GetMagickThreadSignature(),module,
function,
1295 (double) line,domain,event);
1302 for (p=log_info->format; *p !=
'\0'; p++)
1305 if ((
size_t) (q-text+MagickPathExtent) >= extent)
1307 extent+=MagickPathExtent;
1308 text=(
char *) ResizeQuantumMemory(text,extent+MagickPathExtent,
1310 if (text == (
char *) NULL)
1311 return((
char *) NULL);
1312 q=text+strlen(text);
1335 if ((*p ==
'\\') && (*(p+1) ==
'r'))
1341 if ((*p ==
'\\') && (*(p+1) ==
'n'))
1359 q+=CopyMagickString(q,GetClientName(),extent);
1364 q+=CopyMagickString(q,domain,extent);
1369 q+=CopyMagickString(q,event,extent);
1374 q+=CopyMagickString(q,
function,extent);
1379 if (log_info->generations == 0)
1381 (void) CopyMagickString(q,
"0",extent);
1385 q+=FormatLocaleString(q,extent,
"%.20g",(
double) (log_info->generation %
1386 log_info->generations));
1391 q+=FormatLocaleString(q,extent,
"%.20g",(
double)
1392 GetMagickThreadSignature());
1397 q+=FormatLocaleString(q,extent,
"%.20g",(
double) line);
1405 for (r=module+strlen(module)-1; r > module; r--)
1406 if (*r == *DirectorySeparator)
1411 q+=CopyMagickString(q,r,extent);
1416 q+=CopyMagickString(q,GetLogName(),extent);
1421 q+=FormatLocaleString(q,extent,
"%.20g",(
double) getpid());
1426 q+=FormatLocaleString(q,extent,
"%lu:%02lu.%03lu",(
unsigned long)
1427 (elapsed_time/60.0),(
unsigned long) floor(fmod(elapsed_time,60.0)),
1428 (
unsigned long) (1000.0*(elapsed_time-floor(elapsed_time))+0.5));
1433 q+=FormatMagickTime(seconds,extent,q);
1438 q+=FormatLocaleString(q,extent,
"%0.3fu",user_time);
1443 q+=CopyMagickString(q,MagickLibVersionText,extent);
1463 static char *TranslateFilename(
const LogInfo *log_info)
1480 assert(log_info != (
LogInfo *) NULL);
1481 assert(log_info->filename != (
char *) NULL);
1482 filename=AcquireString((
char *) NULL);
1483 extent=MagickPathExtent;
1485 for (p=log_info->filename; *p !=
'\0'; p++)
1488 if ((
size_t) (q-filename+MagickPathExtent) >= extent)
1490 extent+=MagickPathExtent;
1491 filename=(
char *) ResizeQuantumMemory(filename,extent+MagickPathExtent,
1493 if (filename == (
char *) NULL)
1494 return((
char *) NULL);
1495 q=filename+strlen(filename);
1524 q+=CopyMagickString(q,GetClientName(),extent);
1529 if (log_info->generations == 0)
1531 (void) CopyMagickString(q,
"0",extent);
1535 q+=FormatLocaleString(q,extent,
"%.20g",(
double) (log_info->generation %
1536 log_info->generations));
1541 q+=CopyMagickString(q,GetLogName(),extent);
1546 q+=FormatLocaleString(q,extent,
"%.20g",(
double) getpid());
1551 q+=CopyMagickString(q,MagickLibVersionText,extent);
1571 MagickExport MagickBooleanType LogMagickEventList(
const LogEventType type,
1572 const char *module,
const char *
function,
const size_t line,
const char *format,
1576 event[MagickPathExtent],
1591 exception=AcquireExceptionInfo();
1592 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1593 exception=DestroyExceptionInfo(exception);
1595 ActivateSemaphoreInfo(&log_info->event_semaphore);
1596 LockSemaphoreInfo(log_info->event_semaphore);
1597 if ((log_info->event_mask & type) == 0)
1599 UnlockSemaphoreInfo(log_info->event_semaphore);
1602 domain=CommandOptionToMnemonic(MagickLogEventOptions,type);
1603 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
1604 n=vsnprintf(event,MagickPathExtent,format,operands);
1606 n=vsprintf(event,format,operands);
1609 event[MagickPathExtent-1]=
'\0';
1610 text=TranslateEvent(module,
function,line,domain,event);
1611 if (text == (
char *) NULL)
1613 (void) ContinueTimer((
TimerInfo *) &log_info->timer);
1614 UnlockSemaphoreInfo(log_info->event_semaphore);
1615 return(MagickFalse);
1617 if ((log_info->handler_mask & ConsoleHandler) != 0)
1619 (void) FormatLocaleFile(stderr,
"%s\n",text);
1620 (void) fflush(stderr);
1622 if ((log_info->handler_mask & DebugHandler) != 0)
1624 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1625 OutputDebugString(text);
1626 OutputDebugString(
"\n");
1629 if ((log_info->handler_mask & EventHandler) != 0)
1631 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1632 (void) NTReportEvent(text,MagickFalse);
1635 if ((log_info->handler_mask & FileHandler) != 0)
1640 file_info.st_size=0;
1641 if (log_info->file != (FILE *) NULL)
1642 (
void) fstat(fileno(log_info->file),&file_info);
1643 if (file_info.st_size > (MagickOffsetType) (1024*1024*log_info->limit))
1645 (void) FormatLocaleFile(log_info->file,
"</log>\n");
1646 (void) fclose(log_info->file);
1647 log_info->file=(FILE *) NULL;
1649 if (log_info->file == (FILE *) NULL)
1654 filename=TranslateFilename(log_info);
1655 if (filename == (
char *) NULL)
1657 (void) ContinueTimer((
TimerInfo *) &log_info->timer);
1658 UnlockSemaphoreInfo(log_info->event_semaphore);
1659 return(MagickFalse);
1661 log_info->append=IsPathAccessible(filename);
1662 log_info->file=fopen_utf8(filename,
"ab");
1663 filename=(
char *) RelinquishMagickMemory(filename);
1664 if (log_info->file == (FILE *) NULL)
1666 UnlockSemaphoreInfo(log_info->event_semaphore);
1667 return(MagickFalse);
1669 log_info->generation++;
1670 if (log_info->append == MagickFalse)
1671 (void) FormatLocaleFile(log_info->file,
"<?xml version=\"1.0\" "
1672 "encoding=\"UTF-8\" standalone=\"yes\"?>\n");
1673 (void) FormatLocaleFile(log_info->file,
"<log>\n");
1675 (void) FormatLocaleFile(log_info->file,
" <event>%s</event>\n",text);
1676 (void) fflush(log_info->file);
1678 if ((log_info->handler_mask & MethodHandler) != 0)
1680 if (log_info->method != (MagickLogMethod) NULL)
1681 log_info->method(type,text);
1683 if ((log_info->handler_mask & StdoutHandler) != 0)
1685 (void) FormatLocaleFile(stdout,
"%s\n",text);
1686 (void) fflush(stdout);
1688 if ((log_info->handler_mask & StderrHandler) != 0)
1690 (void) FormatLocaleFile(stderr,
"%s\n",text);
1691 (void) fflush(stderr);
1693 text=(
char *) RelinquishMagickMemory(text);
1694 (void) ContinueTimer((
TimerInfo *) &log_info->timer);
1695 UnlockSemaphoreInfo(log_info->event_semaphore);
1699 MagickExport MagickBooleanType LogMagickEvent(
const LogEventType type,
1700 const char *module,
const char *
function,
const size_t line,
1701 const char *format,...)
1709 if (IsEventLogging() == MagickFalse)
1710 return(MagickFalse);
1711 va_start(operands,format);
1712 status=LogMagickEventList(type,module,
function,line,format,operands);
1717 #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
1741 static LogHandlerType ParseLogHandlers(
const char *handlers)
1755 handler_mask=NoHandler;
1756 for (p=handlers; p != (
char *) NULL; p=strchr(p,
','))
1758 while ((*p !=
'\0') && ((isspace((
int) ((
unsigned char) *p)) != 0) ||
1761 for (i=0; *LogHandlers[i].name !=
'\0'; i++)
1763 length=strlen(LogHandlers[i].name);
1764 if (LocaleNCompare(p,LogHandlers[i].name,length) == 0)
1766 handler_mask=(LogHandlerType) (handler_mask | LogHandlers[i].handler);
1770 if (*LogHandlers[i].name ==
'\0')
1771 return(UndefinedHandler);
1773 return(handler_mask);
1801 MagickExport LogEventType SetLogEventMask(
const char *events)
1812 exception=AcquireExceptionInfo();
1813 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1814 exception=DestroyExceptionInfo(exception);
1815 option=ParseCommandOption(MagickLogEventOptions,MagickTrue,events);
1816 LockSemaphoreInfo(log_semaphore);
1817 log_info=(
LogInfo *) GetValueFromLinkedList(log_cache,0);
1818 log_info->event_mask=(LogEventType) option;
1820 log_info->event_mask=UndefinedEvents;
1821 CheckEventLogging();
1822 UnlockSemaphoreInfo(log_semaphore);
1823 return(log_info->event_mask);
1848 MagickExport
void SetLogFormat(
const char *format)
1856 exception=AcquireExceptionInfo();
1857 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1858 exception=DestroyExceptionInfo(exception);
1859 LockSemaphoreInfo(log_semaphore);
1860 if (log_info->format != (
char *) NULL)
1861 log_info->format=DestroyString(log_info->format);
1862 log_info->format=ConstantString(format);
1863 UnlockSemaphoreInfo(log_semaphore);
1889 MagickExport
void SetLogMethod(MagickLogMethod method)
1897 exception=AcquireExceptionInfo();
1898 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1899 exception=DestroyExceptionInfo(exception);
1900 LockSemaphoreInfo(log_semaphore);
1901 log_info=(
LogInfo *) GetValueFromLinkedList(log_cache,0);
1902 log_info->handler_mask=(LogHandlerType) (log_info->handler_mask |
1904 log_info->method=method;
1905 UnlockSemaphoreInfo(log_semaphore);
1932 MagickExport
const char *SetLogName(
const char *name)
1934 if ((name != (
char *) NULL) && (*name !=
'\0'))
1935 (void) CopyMagickString(log_name,name,MagickPathExtent);