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/linked-list-private.h"
51#include "MagickCore/log.h"
52#include "MagickCore/log-private.h"
53#include "MagickCore/memory_.h"
54#include "MagickCore/nt-base-private.h"
55#include "MagickCore/option.h"
56#include "MagickCore/semaphore.h"
57#include "MagickCore/timer.h"
58#include "MagickCore/string_.h"
59#include "MagickCore/string-private.h"
60#include "MagickCore/thread_.h"
61#include "MagickCore/thread-private.h"
62#include "MagickCore/timer-private.h"
63#include "MagickCore/token.h"
64#include "MagickCore/utility.h"
65#include "MagickCore/utility-private.h"
66#include "MagickCore/version.h"
67#include "MagickCore/xml-tree.h"
68#include "MagickCore/xml-tree-private.h"
73#define LogFilename "log.xml"
80 UndefinedHandler = 0x0000,
82 ConsoleHandler = 0x0001,
83 StdoutHandler = 0x0002,
84 StderrHandler = 0x0004,
86 DebugHandler = 0x0010,
87 EventHandler = 0x0020,
88 MethodHandler = 0x0040
169 {
"Console", ConsoleHandler },
170 {
"Debug", DebugHandler },
171 {
"Event", EventHandler },
172 {
"File", FileHandler },
173 {
"None", NoHandler },
174 {
"Stderr", StderrHandler },
175 {
"Stdout", StdoutHandler },
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 },
200 {
"", UndefinedHandler }
206 { NoEvents, ConsoleHandler,
"Magick-%g.log",
207 "%t %r %u %v %d %c[%p]: %m/%f/%l/%d\\n %e" }
211 log_name[MagickPathExtent] =
"Magick";
216static MagickBooleanType
217 event_logging = MagickFalse;
225#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
227 ParseLogHandlers(
const char *) magick_attribute((__pure__));
233static MagickBooleanType
234 IsLogCacheInstantiated(
ExceptionInfo *) magick_attribute((__pure__));
236#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
237static MagickBooleanType
238 LoadLogCache(
LinkedListInfo *,
const char *,
const char *,
const size_t,
283 cache=NewLinkedList(0);
285#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
293 options=GetConfigureOptions(filename,exception);
294 option=(
const StringInfo *) GetNextValueInLinkedList(options);
297 status&=(MagickStatusType) LoadLogCache(cache,(
const char *)
298 GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
299 option=(
const StringInfo *) GetNextValueInLinkedList(options);
301 options=DestroyConfigureOptions(options);
304 magick_unreferenced(filename);
309 for (i=0; i < (ssize_t) (
sizeof(LogMap)/
sizeof(*LogMap)); i++)
318 log_info=(
LogInfo *) AcquireMagickMemory(
sizeof(*log_info));
319 if (log_info == (
LogInfo *) NULL)
321 (void) ThrowMagickException(exception,GetMagickModule(),
322 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",p->filename);
325 (void) memset(log_info,0,
sizeof(*log_info));
326 log_info->path=ConstantString(
"[built-in]");
327 GetTimerInfo((
TimerInfo *) &log_info->timer);
328 log_info->event_mask=p->event_mask;
329 log_info->handler_mask=p->handler_mask;
330 log_info->filename=ConstantString(p->filename);
331 log_info->format=ConstantString(p->format);
332 log_info->signature=MagickCoreSignature;
333 status&=(MagickStatusType) AppendValueToLinkedList(cache,log_info);
334 if (status == MagickFalse)
335 (void) ThrowMagickException(exception,GetMagickModule(),
336 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",log_info->name);
359MagickExport
void CloseMagickLog(
void)
367 if (IsEventLogging() == MagickFalse)
369 exception=AcquireExceptionInfo();
370 log_info=GetLogInfo(
"*",exception);
371 exception=DestroyExceptionInfo(exception);
372 LockSemaphoreInfo(log_semaphore);
373 if (log_info->file != (FILE *) NULL)
375 (void) FormatLocaleFile(log_info->file,
"</log>\n");
376 (void) fclose(log_info->file);
377 log_info->file=(FILE *) NULL;
379 UnlockSemaphoreInfo(log_semaphore);
400MagickExport LogEventType GetLogEventMask(
void)
408 exception=AcquireExceptionInfo();
409 log_info=GetLogInfo(
"*",exception);
410 exception=DestroyExceptionInfo(exception);
411 if (log_info == (
const LogInfo *) NULL)
413 return(log_info->event_mask);
450 if (IsLogCacheInstantiated(exception) == MagickFalse)
456 LockSemaphoreInfo(log_semaphore);
457 p=GetHeadElementInLinkedList(log_cache);
458 if ((name == (
const char *) NULL) || (LocaleCompare(name,
"*") == 0))
462 UnlockSemaphoreInfo(log_semaphore);
468 if (LocaleCompare(name,log_info->name) == 0)
475 SetHeadElementInLinkedList(log_cache,p);
476 UnlockSemaphoreInfo(log_semaphore);
507#if defined(__cplusplus) || defined(c_plusplus)
511static int LogInfoCompare(
const void *x,
const void *y)
519 if (LocaleCompare((*p)->path,(*q)->path) == 0)
520 return(LocaleCompare((*p)->name,(*q)->name));
521 return(LocaleCompare((*p)->path,(*q)->path));
524#if defined(__cplusplus) || defined(c_plusplus)
528MagickExport
const LogInfo **GetLogInfoList(
const char *pattern,
540 assert(pattern != (
char *) NULL);
541 assert(number_preferences != (
size_t *) NULL);
542 if (IsEventLogging() != MagickFalse)
543 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
544 *number_preferences=0;
545 if (IsLogCacheInstantiated(exception) == MagickFalse)
546 return((
const LogInfo **) NULL);
547 preferences=(
const LogInfo **) AcquireQuantumMemory((
size_t)
548 GetNumberOfElementsInLinkedList(log_cache)+1UL,
sizeof(*preferences));
549 if (preferences == (
const LogInfo **) NULL)
550 return((
const LogInfo **) NULL);
551 LockSemaphoreInfo(log_semaphore);
552 p=GetHeadElementInLinkedList(log_cache);
558 log_info=(
const LogInfo *) p->value;
559 if ((log_info->stealth == MagickFalse) &&
560 (GlobExpression(log_info->name,pattern,MagickFalse) != MagickFalse))
561 preferences[i++]=log_info;
564 UnlockSemaphoreInfo(log_semaphore);
566 preferences=(
const LogInfo **) RelinquishMagickMemory((
void*) preferences);
569 qsort((
void *) preferences,(
size_t) i,
sizeof(*preferences),LogInfoCompare);
570 preferences[i]=(
LogInfo *) NULL;
572 *number_preferences=(size_t) i;
604#if defined(__cplusplus) || defined(c_plusplus)
608static int LogCompare(
const void *x,
const void *y)
616 return(LocaleCompare(*p,*q));
619#if defined(__cplusplus) || defined(c_plusplus)
623MagickExport
char **GetLogList(
const char *pattern,
size_t *number_preferences,
635 assert(pattern != (
char *) NULL);
636 assert(number_preferences != (
size_t *) NULL);
637 if (IsEventLogging() != MagickFalse)
638 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
639 *number_preferences=0;
640 if (IsLogCacheInstantiated(exception) == MagickFalse)
641 return((
char **) NULL);
642 preferences=(
char **) AcquireQuantumMemory((
size_t)
643 GetNumberOfElementsInLinkedList(log_cache)+1UL,
sizeof(*preferences));
644 if (preferences == (
char **) NULL)
645 return((
char **) NULL);
646 LockSemaphoreInfo(log_semaphore);
647 p=GetHeadElementInLinkedList(log_cache);
653 log_info=(
const LogInfo *) p->value;
654 if ((log_info->stealth == MagickFalse) &&
655 (GlobExpression(log_info->name,pattern,MagickFalse) != MagickFalse))
656 preferences[i++]=ConstantString(log_info->name);
659 UnlockSemaphoreInfo(log_semaphore);
661 preferences=(
char **) RelinquishMagickMemory(preferences);
664 qsort((
void *) preferences,(
size_t) i,
sizeof(*preferences),LogCompare);
665 preferences[i]=(
char *) NULL;
667 *number_preferences=(size_t) i;
689MagickExport
const char *GetLogName(
void)
718static inline void CheckEventLogging(
void)
723 if (IsLinkedListEmpty(log_cache) != MagickFalse)
724 event_logging=MagickFalse;
730 p=GetHeadElementInLinkedList(log_cache);
732 (((
LogInfo *) p->value)->event_mask != NoEvents) ?
733 MagickTrue: MagickFalse;
737static MagickBooleanType IsLogCacheInstantiated(
ExceptionInfo *exception)
742 ActivateSemaphoreInfo(&log_semaphore);
743 LockSemaphoreInfo(log_semaphore);
746 log_cache=AcquireLogCache(LogFilename,exception);
749 UnlockSemaphoreInfo(log_semaphore);
751 return(log_cache != (
LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
773MagickExport MagickBooleanType IsEventLogging(
void)
775 return(event_logging);
802MagickExport MagickBooleanType ListLogInfo(FILE *file,
ExceptionInfo *exception)
804#define MegabytesToBytes(value) ((MagickSizeType) (value)*1024*1024)
821 if (file == (
const FILE *) NULL)
823 log_info=GetLogInfoList(
"*",&number_aliases,exception);
824 if (log_info == (
const LogInfo **) NULL)
827 path=(
const char *) NULL;
828 for (i=0; i < (ssize_t) number_aliases; i++)
830 if (log_info[i]->stealth != MagickFalse)
832 if ((path == (
const char *) NULL) ||
833 (LocaleCompare(path,log_info[i]->path) != 0))
838 if (log_info[i]->path != (
char *) NULL)
839 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",log_info[i]->path);
841 for (j=0; j < (ssize_t) (8*
sizeof(LogHandlerType)); j++)
846 if (*LogHandlers[j].name ==
'\0')
850 if (((
size_t) log_info[i]->handler_mask & mask) != 0)
852 (void) FormatLocaleFile(file,
"%s ",LogHandlers[j].name);
853 length+=strlen(LogHandlers[j].name);
856 for (j=(ssize_t) length; j <= 12; j++)
857 (
void) FormatLocaleFile(file,
" ");
858 (void) FormatLocaleFile(file,
" Generations Limit Format\n");
859 (void) FormatLocaleFile(file,
"-----------------------------------------"
860 "--------------------------------------\n");
862 path=log_info[i]->path;
863 if (log_info[i]->filename != (
char *) NULL)
865 (void) FormatLocaleFile(file,
"%s",log_info[i]->filename);
866 for (j=(ssize_t) strlen(log_info[i]->filename); j <= 16; j++)
867 (
void) FormatLocaleFile(file,
" ");
869 (void) FormatLocaleFile(file,
"%9g ",(
double) log_info[i]->generations);
870 (void) FormatLocaleFile(file,
"%8g ",(
double) log_info[i]->limit);
871 if (log_info[i]->format != (
char *) NULL)
872 (void) FormatLocaleFile(file,
"%s",log_info[i]->format);
873 (void) FormatLocaleFile(file,
"\n");
876 log_info=(
const LogInfo **) RelinquishMagickMemory((
void *) log_info);
880#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
911static MagickBooleanType LoadLogCache(
LinkedListInfo *cache,
const char *xml,
912 const char *filename,
const size_t depth,
ExceptionInfo *exception)
915 keyword[MagickPathExtent],
933 if (xml == (
const char *) NULL)
936 token=AcquireString(xml);
937 extent=strlen(token)+MagickPathExtent;
938 for (q=(
const char *) xml; *q !=
'\0'; )
943 (void) GetNextToken(q,&q,extent,token);
946 (void) CopyMagickString(keyword,token,MagickPathExtent);
947 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
952 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
953 (void) GetNextToken(q,&q,extent,token);
956 if (LocaleNCompare(keyword,
"<!--",4) == 0)
961 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
962 (void) GetNextToken(q,&q,extent,token);
965 if (LocaleCompare(keyword,
"<include") == 0)
970 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
972 (void) CopyMagickString(keyword,token,MagickPathExtent);
973 (void) GetNextToken(q,&q,extent,token);
976 (void) GetNextToken(q,&q,extent,token);
977 if (LocaleCompare(keyword,
"file") == 0)
979 if (depth > MagickMaxRecursionDepth)
980 (void) ThrowMagickException(exception,GetMagickModule(),
981 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
985 path[MagickPathExtent],
988 GetPathComponent(filename,HeadPath,path);
990 (void) ConcatenateMagickString(path,DirectorySeparator,
992 if (*token == *DirectorySeparator)
993 (void) CopyMagickString(path,token,MagickPathExtent);
995 (
void) ConcatenateMagickString(path,token,MagickPathExtent);
996 file_xml=FileToXML(path,~0UL);
997 if (file_xml != (
char *) NULL)
999 status&=(MagickStatusType) LoadLogCache(cache,file_xml,
1000 path,depth+1,exception);
1001 file_xml=DestroyString(file_xml);
1008 if (LocaleCompare(keyword,
"<logmap>") == 0)
1013 log_info=(
LogInfo *) AcquireCriticalMemory(
sizeof(*log_info));
1014 (void) memset(log_info,0,
sizeof(*log_info));
1015 log_info->path=ConstantString(filename);
1016 GetTimerInfo((
TimerInfo *) &log_info->timer);
1017 log_info->signature=MagickCoreSignature;
1020 if (log_info == (
LogInfo *) NULL)
1022 if (LocaleCompare(keyword,
"</logmap>") == 0)
1024 status=AppendValueToLinkedList(cache,log_info);
1025 if (status == MagickFalse)
1026 (void) ThrowMagickException(exception,GetMagickModule(),
1027 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",filename);
1031 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1034 (void) GetNextToken(q,&q,extent,token);
1035 (void) GetNextToken(q,&q,extent,token);
1041 if (LocaleCompare((
char *) keyword,
"events") == 0)
1043 log_info->event_mask=(LogEventType) (log_info->event_mask |
1044 ParseCommandOption(MagickLogEventOptions,MagickTrue,token));
1052 if (LocaleCompare((
char *) keyword,
"filename") == 0)
1054 if (log_info->filename != (
char *) NULL)
1055 log_info->filename=(
char *)
1056 RelinquishMagickMemory(log_info->filename);
1057 log_info->filename=ConstantString(token);
1060 if (LocaleCompare((
char *) keyword,
"format") == 0)
1062 if (log_info->format != (
char *) NULL)
1063 log_info->format=(
char *)
1064 RelinquishMagickMemory(log_info->format);
1065 log_info->format=ConstantString(token);
1073 if (LocaleCompare((
char *) keyword,
"generations") == 0)
1075 if (LocaleCompare(token,
"unlimited") == 0)
1077 log_info->generations=(~0UL);
1080 log_info->generations=StringToUnsignedLong(token);
1088 if (LocaleCompare((
char *) keyword,
"limit") == 0)
1090 if (LocaleCompare(token,
"unlimited") == 0)
1092 log_info->limit=(~0UL);
1095 log_info->limit=StringToUnsignedLong(token);
1103 if (LocaleCompare((
char *) keyword,
"output") == 0)
1105 log_info->handler_mask=(LogHandlerType)
1106 (log_info->handler_mask | ParseLogHandlers(token));
1115 token=DestroyString(token);
1117 return(MagickFalse);
1118 return(status != 0 ? MagickTrue : MagickFalse);
1140MagickPrivate MagickBooleanType LogComponentGenesis(
void)
1146 log_semaphore=AcquireSemaphoreInfo();
1147 exception=AcquireExceptionInfo();
1148 (void) GetLogInfo(
"*",exception);
1149 exception=DestroyExceptionInfo(exception);
1172static void *DestroyLogElement(
void *log_info)
1178 if (p->file != (FILE *) NULL)
1180 (void) FormatLocaleFile(p->file,
"</log>\n");
1181 (void) fclose(p->file);
1182 p->file=(FILE *) NULL;
1184 if (p->format != (
char *) NULL)
1185 p->format=DestroyString(p->format);
1186 if (p->path != (
char *) NULL)
1187 p->path=DestroyString(p->path);
1188 if (p->filename != (
char *) NULL)
1189 p->filename=DestroyString(p->filename);
1191 RelinquishSemaphoreInfo(&p->event_semaphore);
1192 p=(
LogInfo *) RelinquishMagickMemory(p);
1193 return((
void *) NULL);
1196MagickPrivate
void LogComponentTerminus(
void)
1199 ActivateSemaphoreInfo(&log_semaphore);
1200 LockSemaphoreInfo(log_semaphore);
1202 log_cache=DestroyLinkedList(log_cache,DestroyLogElement);
1203 event_logging=MagickFalse;
1204 UnlockSemaphoreInfo(log_semaphore);
1205 RelinquishSemaphoreInfo(&log_semaphore);
1242static char *TranslateEvent(
const char *module,
const char *function,
1243 const size_t line,
const char *domain,
const char *event)
1270 exception=AcquireExceptionInfo();
1271 log_info=GetLogInfo(
"*",exception);
1272 exception=DestroyExceptionInfo(exception);
1273 seconds=GetMagickTime();
1274 elapsed_time=GetElapsedTime(&log_info->timer);
1275 user_time=GetUserTime(&log_info->timer);
1276 text=AcquireString(event);
1277 if (log_info->format == (
char *) NULL)
1279 extent=strlen(event)+MagickPathExtent;
1280 if (LocaleCompare(log_info->format,
"xml") == 0)
1283 timestamp[MagickTimeExtent];
1288 (void) FormatMagickTime(seconds,
sizeof(timestamp),timestamp);
1289 (void) FormatLocaleString(text,extent,
1291 " <timestamp>%s</timestamp>\n"
1292 " <elapsed-time>%lu:%02lu.%06lu</elapsed-time>\n"
1293 " <user-time>%0.3f</user-time>\n"
1294 " <process-id>%.20g</process-id>\n"
1295 " <thread-id>%.20g</thread-id>\n"
1296 " <module>%s</module>\n"
1297 " <function>%s</function>\n"
1298 " <line>%.20g</line>\n"
1299 " <domain>%s</domain>\n"
1300 " <event>%s</event>\n"
1301 "</entry>",timestamp,(
unsigned long) (elapsed_time/60.0),
1302 (
unsigned long) floor(fmod(elapsed_time,60.0)),(
unsigned long)
1303 (1000000.0*(elapsed_time-floor(elapsed_time))+0.5),user_time,
1304 (
double) getpid(),(
double) GetMagickThreadSignature(),module,function,
1305 (
double) line,domain,event);
1312 for (p=log_info->format; *p !=
'\0'; p++)
1315 if ((
size_t) (q-text+MagickPathExtent) >= extent)
1317 extent+=MagickPathExtent;
1318 text=(
char *) ResizeQuantumMemory(text,extent+MagickPathExtent,
1320 if (text == (
char *) NULL)
1321 return((
char *) NULL);
1322 q=text+strlen(text);
1345 if ((*p ==
'\\') && (*(p+1) ==
'r'))
1351 if ((*p ==
'\\') && (*(p+1) ==
'n'))
1369 q+=CopyMagickString(q,GetClientName(),extent);
1374 q+=CopyMagickString(q,domain,extent);
1379 q+=CopyMagickString(q,event,extent);
1384 q+=CopyMagickString(q,function,extent);
1389 if (log_info->generations == 0)
1391 (void) CopyMagickString(q,
"0",extent);
1395 q+=FormatLocaleString(q,extent,
"%.20g",(
double) (log_info->generation %
1396 log_info->generations));
1401 q+=FormatLocaleString(q,extent,
"%.20g",(
double)
1402 GetMagickThreadSignature());
1407 q+=FormatLocaleString(q,extent,
"%.20g",(
double) line);
1415 for (r=module+strlen(module)-1; r > module; r--)
1416 if (*r == *DirectorySeparator)
1421 q+=CopyMagickString(q,r,extent);
1426 q+=CopyMagickString(q,GetLogName(),extent);
1431 q+=FormatLocaleString(q,extent,
"%.20g",(
double) getpid());
1436 q+=FormatLocaleString(q,extent,
"%lu:%02lu.%03lu",(
unsigned long)
1437 (elapsed_time/60.0),(
unsigned long) floor(fmod(elapsed_time,60.0)),
1438 (
unsigned long) (1000.0*(elapsed_time-floor(elapsed_time))+0.5));
1443 q+=FormatMagickTime(seconds,extent,q);
1448 q+=FormatLocaleString(q,extent,
"%0.3fu",user_time);
1453 q+=CopyMagickString(q,MagickLibVersionText,extent);
1473static char *TranslateFilename(
const LogInfo *log_info)
1490 assert(log_info != (
LogInfo *) NULL);
1491 assert(log_info->filename != (
char *) NULL);
1492 filename=AcquireString((
char *) NULL);
1493 extent=MagickPathExtent;
1495 for (p=log_info->filename; *p !=
'\0'; p++)
1498 if ((
size_t) (q-filename+MagickPathExtent) >= extent)
1500 extent+=MagickPathExtent;
1501 filename=(
char *) ResizeQuantumMemory(filename,extent+MagickPathExtent,
1503 if (filename == (
char *) NULL)
1504 return((
char *) NULL);
1505 q=filename+strlen(filename);
1534 q+=CopyMagickString(q,GetClientName(),extent);
1539 if (log_info->generations == 0)
1541 (void) CopyMagickString(q,
"0",extent);
1545 q+=FormatLocaleString(q,extent,
"%.20g",(
double) (log_info->generation %
1546 log_info->generations));
1551 q+=CopyMagickString(q,GetLogName(),extent);
1556 q+=FormatLocaleString(q,extent,
"%.20g",(
double) getpid());
1561 q+=CopyMagickString(q,MagickLibVersionText,extent);
1581MagickExport MagickBooleanType LogMagickEventList(
const LogEventType type,
1582 const char *module,
const char *function,
const size_t line,
const char *format,
1586 event[MagickPathExtent],
1601 exception=AcquireExceptionInfo();
1602 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1603 exception=DestroyExceptionInfo(exception);
1605 ActivateSemaphoreInfo(&log_info->event_semaphore);
1606 LockSemaphoreInfo(log_info->event_semaphore);
1607 if ((log_info->event_mask & type) == 0)
1609 UnlockSemaphoreInfo(log_info->event_semaphore);
1612 domain=CommandOptionToMnemonic(MagickLogEventOptions,type);
1613#if defined(MAGICKCORE_HAVE_VSNPRINTF)
1614 n=vsnprintf(event,MagickPathExtent,format,operands);
1616 n=vsprintf(event,format,operands);
1619 event[MagickPathExtent-1]=
'\0';
1620 text=TranslateEvent(module,function,line,domain,event);
1621 if (text == (
char *) NULL)
1623 (void) ContinueTimer((
TimerInfo *) &log_info->timer);
1624 UnlockSemaphoreInfo(log_info->event_semaphore);
1625 return(MagickFalse);
1627 if ((log_info->handler_mask & ConsoleHandler) != 0)
1629 (void) FormatLocaleFile(stderr,
"%s\n",text);
1630 (void) fflush(stderr);
1632 if ((log_info->handler_mask & DebugHandler) != 0)
1634#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1635 OutputDebugString(text);
1636 OutputDebugString(
"\n");
1639 if ((log_info->handler_mask & EventHandler) != 0)
1641#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1642 (void) NTReportEvent(text,MagickFalse);
1645 if ((log_info->handler_mask & FileHandler) != 0)
1650 file_info.st_size=0;
1651 if (log_info->file != (FILE *) NULL)
1652 (void) fstat(fileno(log_info->file),&file_info);
1653 if (file_info.st_size > (MagickOffsetType) (1024*1024*log_info->limit))
1655 (void) FormatLocaleFile(log_info->file,
"</log>\n");
1656 (void) fclose(log_info->file);
1657 log_info->file=(FILE *) NULL;
1659 if (log_info->file == (FILE *) NULL)
1664 filename=TranslateFilename(log_info);
1665 if (filename == (
char *) NULL)
1667 (void) ContinueTimer((
TimerInfo *) &log_info->timer);
1668 UnlockSemaphoreInfo(log_info->event_semaphore);
1669 return(MagickFalse);
1671 log_info->append=IsPathAccessible(filename);
1672 log_info->file=fopen_utf8(filename,
"ab");
1673 filename=(
char *) RelinquishMagickMemory(filename);
1674 if (log_info->file == (FILE *) NULL)
1676 UnlockSemaphoreInfo(log_info->event_semaphore);
1677 return(MagickFalse);
1679 log_info->generation++;
1680 if (log_info->append == MagickFalse)
1681 (void) FormatLocaleFile(log_info->file,
"<?xml version=\"1.0\" "
1682 "encoding=\"UTF-8\" standalone=\"yes\"?>\n");
1683 (void) FormatLocaleFile(log_info->file,
"<log>\n");
1685 (void) FormatLocaleFile(log_info->file,
" <event>%s</event>\n",text);
1686 (void) fflush(log_info->file);
1688 if ((log_info->handler_mask & MethodHandler) != 0)
1690 if (log_info->method != (MagickLogMethod) NULL)
1691 log_info->method(type,text);
1693 if ((log_info->handler_mask & StdoutHandler) != 0)
1695 (void) FormatLocaleFile(stdout,
"%s\n",text);
1696 (void) fflush(stdout);
1698 if ((log_info->handler_mask & StderrHandler) != 0)
1700 (void) FormatLocaleFile(stderr,
"%s\n",text);
1701 (void) fflush(stderr);
1703 text=(
char *) RelinquishMagickMemory(text);
1704 (void) ContinueTimer((
TimerInfo *) &log_info->timer);
1705 UnlockSemaphoreInfo(log_info->event_semaphore);
1709MagickExport MagickBooleanType LogMagickEvent(
const LogEventType type,
1710 const char *module,
const char *function,
const size_t line,
1711 const char *format,...)
1719 if (IsEventLogging() == MagickFalse)
1720 return(MagickFalse);
1721 va_start(operands,format);
1722 status=LogMagickEventList(type,module,function,line,format,operands);
1727#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
1751static LogHandlerType ParseLogHandlers(
const char *handlers)
1765 handler_mask=NoHandler;
1766 for (p=handlers; p != (
char *) NULL; p=strchr(p,
','))
1768 while ((*p !=
'\0') && ((isspace((
int) ((
unsigned char) *p)) != 0) ||
1771 for (i=0; *LogHandlers[i].name !=
'\0'; i++)
1773 length=strlen(LogHandlers[i].name);
1774 if (LocaleNCompare(p,LogHandlers[i].name,length) == 0)
1776 handler_mask=(LogHandlerType) (handler_mask | LogHandlers[i].handler);
1780 if (*LogHandlers[i].name ==
'\0')
1781 return(UndefinedHandler);
1783 return(handler_mask);
1811MagickExport LogEventType SetLogEventMask(
const char *events)
1825 event_mask=UndefinedEvents;
1826 exception=AcquireExceptionInfo();
1827 log_info=GetLogInfo(
"*",exception);
1828 exception=DestroyExceptionInfo(exception);
1829 if (log_info == (
LogInfo *) NULL)
1831 option=ParseCommandOption(MagickLogEventOptions,MagickTrue,events);
1832 LockSemaphoreInfo(log_semaphore);
1833 event_mask=log_info->event_mask;
1835 log_info->event_mask=UndefinedEvents;
1837 log_info->event_mask=(LogEventType) option;
1838 CheckEventLogging();
1839 UnlockSemaphoreInfo(log_semaphore);
1865MagickExport
void SetLogFormat(
const char *format)
1873 exception=AcquireExceptionInfo();
1874 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1875 exception=DestroyExceptionInfo(exception);
1876 if (log_info == (
LogInfo *) NULL)
1878 LockSemaphoreInfo(log_semaphore);
1879 if (log_info->format != (
char *) NULL)
1880 log_info->format=DestroyString(log_info->format);
1881 log_info->format=ConstantString(format);
1882 UnlockSemaphoreInfo(log_semaphore);
1908MagickExport
void SetLogMethod(MagickLogMethod method)
1916 exception=AcquireExceptionInfo();
1917 log_info=(
LogInfo *) GetLogInfo(
"*",exception);
1918 exception=DestroyExceptionInfo(exception);
1919 LockSemaphoreInfo(log_semaphore);
1920 log_info=(
LogInfo *) GetValueFromLinkedList(log_cache,0);
1921 log_info->handler_mask=(LogHandlerType) (log_info->handler_mask |
1923 log_info->method=method;
1924 UnlockSemaphoreInfo(log_semaphore);
1951MagickExport
const char *SetLogName(
const char *name)
1953 if ((name != (
char *) NULL) && (*name !=
'\0'))
1954 (void) CopyMagickString(log_name,name,MagickPathExtent);