42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/client.h"
45#include "magick/configure.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/hashmap.h"
49#include "magick/log.h"
50#include "magick/memory_.h"
51#include "magick/nt-base-private.h"
52#include "magick/option.h"
53#include "magick/semaphore.h"
54#include "magick/timer.h"
55#include "magick/string_.h"
56#include "magick/string-private.h"
57#include "magick/token.h"
58#include "magick/thread_.h"
59#include "magick/thread-private.h"
60#include "magick/timer-private.h"
61#include "magick/utility.h"
62#include "magick/utility-private.h"
63#include "magick/version.h"
64#include "magick/xml-tree.h"
65#include "magick/xml-tree-private.h"
70#define LogFilename "log.xml"
77 UndefinedHandler = 0x0000,
79 ConsoleHandler = 0x0001,
80 StdoutHandler = 0x0002,
81 StderrHandler = 0x0004,
83 DebugHandler = 0x0010,
84 EventHandler = 0x0020,
85 MethodHandler = 0x0040
163static const HandlerInfo
166 {
"Console", ConsoleHandler },
167 {
"Debug", DebugHandler },
168 {
"Event", EventHandler },
169 {
"File", FileHandler },
170 {
"None", NoHandler },
171 {
"Stderr", StderrHandler },
172 {
"Stdout", StdoutHandler },
173 {
"", UndefinedHandler },
174 {
"", UndefinedHandler },
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 }
200static const LogMapInfo
203 { NoEvents, ConsoleHandler,
"Magick-%g.log",
204 "%t %r %u %v %d %c[%p]: %m/%f/%l/%d\\n %e" }
208 log_name[MaxTextExtent] =
"Magick";
211 *log_cache = (LinkedListInfo *) NULL;
213static MagickBooleanType
214 event_logging = MagickFalse;
222#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
224 ParseLogHandlers(
const char *) magick_attribute((__pure__));
228 *GetLogInfo(
const char *,ExceptionInfo *);
230static MagickBooleanType
231 IsLogCacheInstantiated(ExceptionInfo *) magick_attribute((__pure__));
233#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
234static MagickBooleanType
235 LoadLogCache(LinkedListInfo *,
const char *,
const char *,
const size_t,
265static LinkedListInfo *AcquireLogCache(
const char *filename,
266 ExceptionInfo *exception)
280 cache=NewLinkedList(0);
281 if (cache == (LinkedListInfo *) NULL)
282 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
284#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
292 options=GetConfigureOptions(filename,exception);
293 option=(
const StringInfo *) GetNextValueInLinkedList(options);
294 while (option != (
const StringInfo *) NULL)
296 status&=LoadLogCache(cache,(
const char *) GetStringInfoDatum(option),
297 GetStringInfoPath(option),0,exception);
298 option=(
const StringInfo *) GetNextValueInLinkedList(options);
300 options=DestroyConfigureOptions(options);
306 for (i=0; i < (ssize_t) (
sizeof(LogMap)/
sizeof(*LogMap)); i++)
315 log_info=(LogInfo *) AcquireMagickMemory(
sizeof(*log_info));
316 if (log_info == (LogInfo *) NULL)
318 (void) ThrowMagickException(exception,GetMagickModule(),
319 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",p->filename);
322 (void) memset(log_info,0,
sizeof(*log_info));
323 log_info->path=ConstantString(
"[built-in]");
324 GetTimerInfo((TimerInfo *) &log_info->timer);
325 log_info->event_mask=p->event_mask;
326 log_info->handler_mask=p->handler_mask;
327 log_info->filename=ConstantString(p->filename);
328 log_info->format=ConstantString(p->format);
329 log_info->signature=MagickCoreSignature;
330 status&=AppendValueToLinkedList(cache,log_info);
331 if (status == MagickFalse)
332 (void) ThrowMagickException(exception,GetMagickModule(),
333 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",log_info->name);
356MagickExport
void CloseMagickLog(
void)
364 if (IsEventLogging() == MagickFalse)
366 exception=AcquireExceptionInfo();
367 log_info=GetLogInfo(
"*",exception);
368 exception=DestroyExceptionInfo(exception);
369 if (log_info == (LogInfo *) NULL)
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);
399MagickExport 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);
440static LogInfo *GetLogInfo(
const char *name,ExceptionInfo *exception)
445 assert(exception != (ExceptionInfo *) NULL);
446 if (IsLogCacheInstantiated(exception) == MagickFalse)
447 return((LogInfo *) NULL);
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);
459 while (p != (LogInfo *) NULL)
461 if (LocaleCompare(name,p->name) == 0)
463 p=(LogInfo *) GetNextValueInLinkedList(log_cache);
465 if (p != (LogInfo *) NULL)
466 (void) InsertValueInLinkedList(log_cache,0,
467 RemoveElementByValueFromLinkedList(log_cache,p));
468 UnlockSemaphoreInfo(log_semaphore);
499#if defined(__cplusplus) || defined(c_plusplus)
503static int LogInfoCompare(
const void *x,
const void *y)
509 p=(
const LogInfo **) x,
510 q=(
const LogInfo **) 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)
520MagickExport
const LogInfo **GetLogInfoList(
const char *pattern,
521 size_t *number_preferences,ExceptionInfo *exception)
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)
599static int LogCompare(
const void *x,
const void *y)
607 return(LocaleCompare(*p,*q));
610#if defined(__cplusplus) || defined(c_plusplus)
614MagickExport
char **GetLogList(
const char *pattern,
615 size_t *number_preferences,ExceptionInfo *exception)
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;
679MagickExport
char *GetLogName(
void)
708static inline void CheckEventLogging(
void)
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;
727static MagickBooleanType IsLogCacheInstantiated(ExceptionInfo *exception)
729 if (log_cache == (LinkedListInfo *) NULL)
732 ActivateSemaphoreInfo(&log_semaphore);
733 LockSemaphoreInfo(log_semaphore);
734 if (log_cache == (LinkedListInfo *) NULL)
736 log_cache=AcquireLogCache(LogFilename,exception);
739 UnlockSemaphoreInfo(log_semaphore);
741 return(log_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
763MagickExport MagickBooleanType IsEventLogging(
void)
765 return(event_logging);
791MagickExport MagickBooleanType ListLogInfo(FILE *file,ExceptionInfo *exception)
793#define MegabytesToBytes(value) ((MagickSizeType) (value)*1024*1024)
810 if (file == (
const FILE *) NULL)
812 log_info=GetLogInfoList(
"*",&number_aliases,exception);
813 if (log_info == (
const LogInfo **) NULL)
816 path=(
const char *) NULL;
817 for (i=0; i < (ssize_t) number_aliases; i++)
819 if (log_info[i]->stealth != MagickFalse)
821 if ((path == (
const char *) NULL) ||
822 (LocaleCompare(path,log_info[i]->path) != 0))
827 if (log_info[i]->path != (
char *) NULL)
828 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",log_info[i]->path);
830 for (j=0; j < (ssize_t) (8*
sizeof(LogHandlerType)); j++)
835 if (*LogHandlers[j].name ==
'\0')
839 if ((log_info[i]->handler_mask & mask) != 0)
841 (void) FormatLocaleFile(file,
"%s ",LogHandlers[j].name);
842 length+=strlen(LogHandlers[j].name);
845 for (j=(ssize_t) length; j <= 12; j++)
846 (
void) FormatLocaleFile(file,
" ");
847 (void) FormatLocaleFile(file,
" Generations Limit Format\n");
848 (void) FormatLocaleFile(file,
"-----------------------------------------"
849 "--------------------------------------\n");
851 path=log_info[i]->path;
852 if (log_info[i]->filename != (
char *) NULL)
854 (void) FormatLocaleFile(file,
"%s",log_info[i]->filename);
855 for (j=(ssize_t) strlen(log_info[i]->filename); j <= 16; j++)
856 (
void) FormatLocaleFile(file,
" ");
858 (void) FormatLocaleFile(file,
"%9g ",(
double) log_info[i]->generations);
859 (void) FormatLocaleFile(file,
"%8g ",(
double) log_info[i]->limit);
860 if (log_info[i]->format != (
char *) NULL)
861 (void) FormatLocaleFile(file,
"%s",log_info[i]->format);
862 (void) FormatLocaleFile(file,
"\n");
865 log_info=(
const LogInfo **) RelinquishMagickMemory((
void *) log_info);
887MagickExport MagickBooleanType LogComponentGenesis(
void)
893 log_semaphore=AllocateSemaphoreInfo();
894 exception=AcquireExceptionInfo();
895 (void) GetLogInfo(
"*",exception);
896 exception=DestroyExceptionInfo(exception);
919static void *DestroyLogElement(
void *log_info)
924 p=(LogInfo *) log_info;
925 if (p->file != (FILE *) NULL)
927 (void) FormatLocaleFile(p->file,
"</log>\n");
928 (void) fclose(p->file);
929 p->file=(FILE *) NULL;
931 if (p->format != (
char *) NULL)
932 p->format=DestroyString(p->format);
933 if (p->path != (
char *) NULL)
934 p->path=DestroyString(p->path);
935 if (p->filename != (
char *) NULL)
936 p->filename=DestroyString(p->filename);
938 DestroySemaphoreInfo(&p->event_semaphore);
939 p=(LogInfo *) RelinquishMagickMemory(p);
940 return((
void *) NULL);
943MagickExport
void LogComponentTerminus(
void)
946 ActivateSemaphoreInfo(&log_semaphore);
947 LockSemaphoreInfo(log_semaphore);
948 if (log_cache != (LinkedListInfo *) NULL)
949 log_cache=DestroyLinkedList(log_cache,DestroyLogElement);
950 event_logging=MagickFalse;
951 UnlockSemaphoreInfo(log_semaphore);
952 DestroySemaphoreInfo(&log_semaphore);
988static char *TranslateEvent(
const LogEventType magick_unused(type),
989 const char *module,
const char *function,
const size_t line,
const char *domain,
1017 magick_unreferenced(type);
1019 exception=AcquireExceptionInfo();
1020 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1021 exception=DestroyExceptionInfo(exception);
1022 text=AcquireString(event);
1023 if (log_info == (LogInfo *) NULL)
1025 seconds=GetMagickTime();
1026 elapsed_time=GetElapsedTime(&log_info->timer);
1027 user_time=GetUserTime(&log_info->timer);
1028 if (log_info->format == (
char *) NULL)
1030 extent=strlen(event)+MaxTextExtent;
1031 if (LocaleCompare(log_info->format,
"xml") == 0)
1034 timestamp[MaxTextExtent];
1039 (void) FormatMagickTime(seconds,extent,timestamp);
1040 (void) FormatLocaleString(text,extent,
1042 " <timestamp>%s</timestamp>\n"
1043 " <elapsed-time>%lu:%02lu.%06lu</elapsed-time>\n"
1044 " <user-time>%0.3f</user-time>\n"
1045 " <process-id>%.20g</process-id>\n"
1046 " <thread-id>%.20g</thread-id>\n"
1047 " <module>%s</module>\n"
1048 " <function>%s</function>\n"
1049 " <line>%.20g</line>\n"
1050 " <domain>%s</domain>\n"
1051 " <event>%s</event>\n"
1052 "</entry>",timestamp,(
unsigned long) (elapsed_time/60.0),
1053 (
unsigned long) floor(fmod(elapsed_time,60.0)),(
unsigned long)
1054 (1000000.0*(elapsed_time-floor(elapsed_time))+0.5),user_time,
1055 (
double) getpid(),(
double) GetMagickThreadSignature(),module,function,
1056 (
double) line,domain,event);
1063 for (p=log_info->format; *p !=
'\0'; p++)
1066 if ((
size_t) (q-text+MaxTextExtent) >= extent)
1069 text=(
char *) ResizeQuantumMemory(text,extent,
sizeof(*text));
1070 if (text == (
char *) NULL)
1071 return((
char *) NULL);
1072 q=text+strlen(text);
1095 if ((*p ==
'\\') && (*(p+1) ==
'r'))
1101 if ((*p ==
'\\') && (*(p+1) ==
'n'))
1119 q+=(ptrdiff_t) CopyMagickString(q,GetClientName(),extent-(q-text));
1124 q+=(ptrdiff_t) CopyMagickString(q,domain,extent-(q-text));
1129 q+=(ptrdiff_t) CopyMagickString(q,event,extent-(q-text));
1134 q+=(ptrdiff_t) CopyMagickString(q,function,extent-(q-text));
1139 if (log_info->generations == 0)
1141 (void) CopyMagickString(q,
"0",extent-(q-text));
1145 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%.20g",(
double)
1146 (log_info->generation % log_info->generations));
1151 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%.20g",(
double)
1152 GetMagickThreadSignature());
1157 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%.20g",(
double)
1166 for (p=module+strlen(module)-1; p > module; p--)
1167 if (*p == *DirectorySeparator)
1172 q+=(ptrdiff_t) CopyMagickString(q,p,extent-(q-text));
1177 q+=(ptrdiff_t) CopyMagickString(q,GetLogName(),extent-(q-text));
1182 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%.20g",(
double)
1188 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%lu:%02lu.%03lu",
1189 (
unsigned long) (elapsed_time/60.0),(
unsigned long) floor(fmod(
1190 elapsed_time,60.0)),(
unsigned long) (1000.0*(elapsed_time-floor(
1191 elapsed_time))+0.5));
1196 q+=(ptrdiff_t) FormatMagickTime(seconds,extent-(q-text),q);
1201 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%0.3fu",user_time);
1206 q+=(ptrdiff_t) CopyMagickString(q,MagickLibVersionText,extent-(q-text));
1226static char *TranslateFilename(
const LogInfo *log_info)
1243 assert(log_info != (LogInfo *) NULL);
1244 assert(log_info->filename != (
char *) NULL);
1245 filename=AcquireString((
char *) NULL);
1246 extent=MaxTextExtent;
1248 for (p=log_info->filename; *p !=
'\0'; p++)
1251 if ((
size_t) (q-filename+MaxTextExtent) >= extent)
1254 filename=(
char *) ResizeQuantumMemory(filename,extent,
1256 if (filename == (
char *) NULL)
1257 return((
char *) NULL);
1258 q=filename+strlen(filename);
1287 q+=(ptrdiff_t) CopyMagickString(q,GetClientName(),extent-(q-filename));
1292 if (log_info->generations == 0)
1294 (void) CopyMagickString(q,
"0",extent);
1298 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-filename),
"%.20g",
1299 (
double) (log_info->generation % log_info->generations));
1304 q+=(ptrdiff_t) CopyMagickString(q,GetLogName(),extent-(q-filename));
1309 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-filename),
"%.20g",
1315 q+=(ptrdiff_t) CopyMagickString(q,MagickLibVersionText,extent-
1336MagickExport MagickBooleanType LogMagickEventList(
const LogEventType type,
1337 const char *module,
const char *function,
const size_t line,
const char *format,
1341 event[MaxTextExtent],
1356 exception=AcquireExceptionInfo();
1357 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1358 exception=DestroyExceptionInfo(exception);
1359 if (log_info == (LogInfo *) NULL)
1360 return(MagickFalse);
1362 ActivateSemaphoreInfo(&log_info->event_semaphore);
1363 LockSemaphoreInfo(log_info->event_semaphore);
1364 if ((log_info->event_mask & type) == 0)
1366 UnlockSemaphoreInfo(log_info->event_semaphore);
1369 domain=CommandOptionToMnemonic(MagickLogEventOptions,type);
1370#if defined(MAGICKCORE_HAVE_VSNPRINTF)
1371 n=vsnprintf(event,MaxTextExtent,format,operands);
1373 n=vsprintf(event,format,operands);
1376 event[MaxTextExtent-1]=
'\0';
1377 text=TranslateEvent(type,module,function,line,domain,event);
1378 if (text == (
char *) NULL)
1380 (void) ContinueTimer((TimerInfo *) &log_info->timer);
1381 UnlockSemaphoreInfo(log_info->event_semaphore);
1382 return(MagickFalse);
1384 if ((log_info->handler_mask & ConsoleHandler) != 0)
1386 (void) FormatLocaleFile(stderr,
"%s\n",text);
1387 (void) fflush(stderr);
1389 if ((log_info->handler_mask & DebugHandler) != 0)
1391#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1392 OutputDebugString(text);
1393 OutputDebugString(
"\n");
1396 if ((log_info->handler_mask & EventHandler) != 0)
1398#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1399 (void) NTReportEvent(text,MagickFalse);
1402 if ((log_info->handler_mask & FileHandler) != 0)
1407 file_info.st_size=0;
1408 if (log_info->file != (FILE *) NULL)
1409 (void) fstat(fileno(log_info->file),&file_info);
1410 if (file_info.st_size > (MagickOffsetType) (1024*1024*log_info->limit))
1412 (void) FormatLocaleFile(log_info->file,
"</log>\n");
1413 (void) fclose(log_info->file);
1414 log_info->file=(FILE *) NULL;
1416 if (log_info->file == (FILE *) NULL)
1421 filename=TranslateFilename(log_info);
1422 if (filename == (
char *) NULL)
1424 (void) ContinueTimer((TimerInfo *) &log_info->timer);
1425 UnlockSemaphoreInfo(log_info->event_semaphore);
1426 return(MagickFalse);
1428 log_info->append=IsPathAccessible(filename);
1429 log_info->file=fopen_utf8(filename,
"ab");
1430 filename=(
char *) RelinquishMagickMemory(filename);
1431 if (log_info->file == (FILE *) NULL)
1433 UnlockSemaphoreInfo(log_info->event_semaphore);
1434 return(MagickFalse);
1436 log_info->generation++;
1437 if (log_info->append == MagickFalse)
1438 (void) FormatLocaleFile(log_info->file,
"<?xml version=\"1.0\" "
1439 "encoding=\"UTF-8\" standalone=\"yes\"?>\n");
1440 (void) FormatLocaleFile(log_info->file,
"<log>\n");
1442 (void) FormatLocaleFile(log_info->file,
" <event>%s</event>\n",text);
1443 (void) fflush(log_info->file);
1445 if ((log_info->handler_mask & MethodHandler) != 0)
1447 if (log_info->method != (MagickLogMethod) NULL)
1448 log_info->method(type,text);
1450 if ((log_info->handler_mask & StdoutHandler) != 0)
1452 (void) FormatLocaleFile(stdout,
"%s\n",text);
1453 (void) fflush(stdout);
1455 if ((log_info->handler_mask & StderrHandler) != 0)
1457 (void) FormatLocaleFile(stderr,
"%s\n",text);
1458 (void) fflush(stderr);
1460 text=(
char *) RelinquishMagickMemory(text);
1461 (void) ContinueTimer((TimerInfo *) &log_info->timer);
1462 UnlockSemaphoreInfo(log_info->event_semaphore);
1466MagickExport MagickBooleanType LogMagickEvent(
const LogEventType type,
1467 const char *module,
const char *function,
const size_t line,
1468 const char *format,...)
1476 if (IsEventLogging() == MagickFalse)
1477 return(MagickFalse);
1478 va_start(operands,format);
1479 status=LogMagickEventList(type,module,function,line,format,operands);
1484#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
1515static MagickBooleanType LoadLogCache(LinkedListInfo *cache,
const char *xml,
1516 const char *filename,
const size_t depth,ExceptionInfo *exception)
1519 keyword[MaxTextExtent],
1526 *log_info = (LogInfo *) NULL;
1537 if (xml == (
const char *) NULL)
1538 return(MagickFalse);
1540 token=AcquireString(xml);
1541 extent=strlen(token)+MaxTextExtent;
1542 for (q=(
const char *) xml; *q !=
'\0'; )
1547 (void) GetNextToken(q,&q,extent,token);
1550 (void) CopyMagickString(keyword,token,MaxTextExtent);
1551 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1556 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1557 (void) GetNextToken(q,&q,extent,token);
1560 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1565 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1566 (void) GetNextToken(q,&q,extent,token);
1569 if (LocaleCompare(keyword,
"<include") == 0)
1574 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1576 (void) CopyMagickString(keyword,token,MaxTextExtent);
1577 (void) GetNextToken(q,&q,extent,token);
1580 (void) GetNextToken(q,&q,extent,token);
1581 if (LocaleCompare(keyword,
"file") == 0)
1583 if (depth > MagickMaxRecursionDepth)
1584 (void) ThrowMagickException(exception,GetMagickModule(),
1585 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1589 path[MaxTextExtent],
1592 GetPathComponent(filename,HeadPath,path);
1594 (void) ConcatenateMagickString(path,DirectorySeparator,
1596 if (*token == *DirectorySeparator)
1597 (void) CopyMagickString(path,token,MaxTextExtent);
1599 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
1600 xml=FileToXML(path,~0UL);
1601 if (xml != (
char *) NULL)
1603 status&=LoadLogCache(cache,xml,path,depth+1,
1605 xml=DestroyString(xml);
1612 if (LocaleCompare(keyword,
"<logmap>") == 0)
1617 log_info=(LogInfo *) AcquireMagickMemory(
sizeof(*log_info));
1618 if (log_info == (LogInfo *) NULL)
1619 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1620 (void) memset(log_info,0,
sizeof(*log_info));
1621 log_info->path=ConstantString(filename);
1622 GetTimerInfo((TimerInfo *) &log_info->timer);
1623 log_info->signature=MagickCoreSignature;
1626 if (log_info == (LogInfo *) NULL)
1628 if (LocaleCompare(keyword,
"</logmap>") == 0)
1630 status=AppendValueToLinkedList(cache,log_info);
1631 if (status == MagickFalse)
1632 (void) ThrowMagickException(exception,GetMagickModule(),
1633 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",filename);
1634 log_info=(LogInfo *) NULL;
1637 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1640 (void) GetNextToken(q,&q,extent,token);
1641 (void) GetNextToken(q,&q,extent,token);
1647 if (LocaleCompare((
char *) keyword,
"events") == 0)
1649 log_info->event_mask=(LogEventType) (log_info->event_mask |
1650 ParseCommandOption(MagickLogEventOptions,MagickTrue,token));
1658 if (LocaleCompare((
char *) keyword,
"filename") == 0)
1660 if (log_info->filename != (
char *) NULL)
1661 log_info->filename=(
char *)
1662 RelinquishMagickMemory(log_info->filename);
1663 log_info->filename=ConstantString(token);
1666 if (LocaleCompare((
char *) keyword,
"format") == 0)
1668 if (log_info->format != (
char *) NULL)
1669 log_info->format=(
char *)
1670 RelinquishMagickMemory(log_info->format);
1671 log_info->format=ConstantString(token);
1679 if (LocaleCompare((
char *) keyword,
"generations") == 0)
1681 if (LocaleCompare(token,
"unlimited") == 0)
1683 log_info->generations=(~0UL);
1686 log_info->generations=StringToUnsignedLong(token);
1694 if (LocaleCompare((
char *) keyword,
"limit") == 0)
1696 if (LocaleCompare(token,
"unlimited") == 0)
1698 log_info->limit=(~0UL);
1701 log_info->limit=StringToUnsignedLong(token);
1709 if (LocaleCompare((
char *) keyword,
"output") == 0)
1711 log_info->handler_mask=(LogHandlerType)
1712 (log_info->handler_mask | ParseLogHandlers(token));
1721 token=DestroyString(token);
1722 if (cache == (LinkedListInfo *) NULL)
1723 return(MagickFalse);
1724 return(status != 0 ? MagickTrue : MagickFalse);
1728#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
1752static LogHandlerType ParseLogHandlers(
const char *handlers)
1766 handler_mask=NoHandler;
1767 for (p=handlers; p != (
char *) NULL; p=strchr(p,
','))
1769 while ((*p !=
'\0') && ((isspace((
int) ((
unsigned char) *p)) != 0) ||
1772 for (i=0; *LogHandlers[i].name !=
'\0'; i++)
1774 length=strlen(LogHandlers[i].name);
1775 if (LocaleNCompare(p,LogHandlers[i].name,length) == 0)
1777 handler_mask=(LogHandlerType) (handler_mask | LogHandlers[i].handler);
1781 if (*LogHandlers[i].name ==
'\0')
1782 return(UndefinedHandler);
1784 return(handler_mask);
1812MagickExport LogEventType SetLogEventMask(
const char *events)
1823 exception=AcquireExceptionInfo();
1824 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1825 exception=DestroyExceptionInfo(exception);
1826 if (log_info == (LogInfo *) NULL)
1828 option=ParseCommandOption(MagickLogEventOptions,MagickTrue,events);
1829 LockSemaphoreInfo(log_semaphore);
1830 log_info=(LogInfo *) GetValueFromLinkedList(log_cache,0);
1831 if (log_info == (LogInfo *) NULL)
1833 UnlockSemaphoreInfo(log_semaphore);
1836 log_info->event_mask=(LogEventType) option;
1838 log_info->event_mask=UndefinedEvents;
1839 CheckEventLogging();
1840 UnlockSemaphoreInfo(log_semaphore);
1841 return(log_info->event_mask);
1866MagickExport
void SetLogFormat(
const char *format)
1874 exception=AcquireExceptionInfo();
1875 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1876 exception=DestroyExceptionInfo(exception);
1877 if (log_info == (LogInfo *) NULL)
1879 LockSemaphoreInfo(log_semaphore);
1880 if (log_info->format != (
char *) NULL)
1881 log_info->format=DestroyString(log_info->format);
1882 log_info->format=ConstantString(format);
1883 UnlockSemaphoreInfo(log_semaphore);
1909MagickExport
void SetLogMethod(MagickLogMethod method)
1917 exception=AcquireExceptionInfo();
1918 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1919 exception=DestroyExceptionInfo(exception);
1920 if (log_info == (LogInfo *) NULL)
1922 LockSemaphoreInfo(log_semaphore);
1923 log_info=(LogInfo *) GetValueFromLinkedList(log_cache,0);
1924 if (log_info == (LogInfo *) NULL)
1926 UnlockSemaphoreInfo(log_semaphore);
1929 log_info->handler_mask=(LogHandlerType) (log_info->handler_mask |
1931 log_info->method=method;
1932 UnlockSemaphoreInfo(log_semaphore);
1959MagickExport
char *SetLogName(
const char *name)
1961 if ((name != (
char *) NULL) && (*name !=
'\0'))
1962 (void) CopyMagickString(log_name,name,MaxTextExtent);