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/resource-private.h"
57#include "MagickCore/semaphore.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.h"
63#include "MagickCore/timer-private.h"
64#include "MagickCore/token.h"
65#include "MagickCore/utility.h"
66#include "MagickCore/utility-private.h"
67#include "MagickCore/version.h"
68#include "MagickCore/xml-tree.h"
69#include "MagickCore/xml-tree-private.h"
74#define LogFilename "log.xml"
81 UndefinedHandler = 0x0000,
83 ConsoleHandler = 0x0001,
84 StdoutHandler = 0x0002,
85 StderrHandler = 0x0004,
87 DebugHandler = 0x0010,
88 EventHandler = 0x0020,
89 MethodHandler = 0x0040
166static const HandlerInfo
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 }
203static const LogMapInfo
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";
214 *log_cache = (LinkedListInfo *) NULL;
216static MagickBooleanType
217 event_logging = MagickFalse;
225#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
227 ParseLogHandlers(
const char *) magick_attribute((__pure__));
231 *GetLogInfo(
const char *,ExceptionInfo *);
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,
268static LinkedListInfo *AcquireLogCache(
const char *filename,
269 ExceptionInfo *exception)
283 cache=NewLinkedList(0);
285#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
293 options=GetConfigureOptions(filename,exception);
294 option=(
const StringInfo *) GetNextValueInLinkedList(options);
295 while (option != (
const StringInfo *) NULL)
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 if (log_info == (LogInfo *) NULL)
374 LockSemaphoreInfo(log_semaphore);
375 if ((log_info != (LogInfo *) NULL) && (log_info->file != (FILE *) NULL))
377 (void) FormatLocaleFile(log_info->file,
"</log>\n");
378 (void) fclose(log_info->file);
379 log_info->file=(FILE *) NULL;
381 UnlockSemaphoreInfo(log_semaphore);
402MagickExport LogEventType GetLogEventMask(
void)
410 exception=AcquireExceptionInfo();
411 log_info=GetLogInfo(
"*",exception);
412 exception=DestroyExceptionInfo(exception);
413 if (log_info == (
const LogInfo *) NULL)
415 return(log_info->event_mask);
443static LogInfo *GetLogInfo(
const char *name,ExceptionInfo *exception)
451 assert(exception != (ExceptionInfo *) NULL);
452 if (IsLogCacheInstantiated(exception) == MagickFalse)
453 return((LogInfo *) NULL);
457 log_info=(LogInfo *) NULL;
458 LockSemaphoreInfo(log_semaphore);
459 p=GetHeadElementInLinkedList(log_cache);
460 if ((name == (
const char *) NULL) || (LocaleCompare(name,
"*") == 0))
462 if (p != (ElementInfo *) NULL)
463 log_info=(LogInfo *) p->value;
464 UnlockSemaphoreInfo(log_semaphore);
467 while (p != (ElementInfo *) NULL)
469 log_info=(LogInfo* ) p->value;
470 if (LocaleCompare(name,log_info->name) == 0)
474 if (p == (ElementInfo *) NULL)
475 log_info=(LogInfo *) NULL;
477 SetHeadElementInLinkedList(log_cache,p);
478 UnlockSemaphoreInfo(log_semaphore);
509#if defined(__cplusplus) || defined(c_plusplus)
513static int LogInfoCompare(
const void *x,
const void *y)
519 p=(
const LogInfo **) x,
520 q=(
const LogInfo **) y;
521 if (LocaleCompare((*p)->path,(*q)->path) == 0)
522 return(LocaleCompare((*p)->name,(*q)->name));
523 return(LocaleCompare((*p)->path,(*q)->path));
526#if defined(__cplusplus) || defined(c_plusplus)
530MagickExport
const LogInfo **GetLogInfoList(
const char *pattern,
531 size_t *number_preferences,ExceptionInfo *exception)
542 assert(pattern != (
char *) NULL);
543 assert(number_preferences != (
size_t *) NULL);
544 if (IsEventLogging() != MagickFalse)
545 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
546 *number_preferences=0;
547 if (IsLogCacheInstantiated(exception) == MagickFalse)
548 return((
const LogInfo **) NULL);
549 preferences=(
const LogInfo **) AcquireQuantumMemory((
size_t)
550 GetNumberOfElementsInLinkedList(log_cache)+1UL,
sizeof(*preferences));
551 if (preferences == (
const LogInfo **) NULL)
552 return((
const LogInfo **) NULL);
553 LockSemaphoreInfo(log_semaphore);
554 p=GetHeadElementInLinkedList(log_cache);
555 for (i=0; p != (ElementInfo *) NULL; )
560 log_info=(
const LogInfo *) p->value;
561 if ((log_info->stealth == MagickFalse) &&
562 (GlobExpression(log_info->name,pattern,MagickFalse) != MagickFalse))
563 preferences[i++]=log_info;
566 UnlockSemaphoreInfo(log_semaphore);
568 preferences=(
const LogInfo **) RelinquishMagickMemory((
void*) preferences);
571 qsort((
void *) preferences,(
size_t) i,
sizeof(*preferences),LogInfoCompare);
572 preferences[i]=(LogInfo *) NULL;
574 *number_preferences=(size_t) i;
606#if defined(__cplusplus) || defined(c_plusplus)
610static int LogCompare(
const void *x,
const void *y)
618 return(LocaleCompare(*p,*q));
621#if defined(__cplusplus) || defined(c_plusplus)
625MagickExport
char **GetLogList(
const char *pattern,
size_t *number_preferences,
626 ExceptionInfo *exception)
637 assert(pattern != (
char *) NULL);
638 assert(number_preferences != (
size_t *) NULL);
639 if (IsEventLogging() != MagickFalse)
640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
641 *number_preferences=0;
642 if (IsLogCacheInstantiated(exception) == MagickFalse)
643 return((
char **) NULL);
644 preferences=(
char **) AcquireQuantumMemory((
size_t)
645 GetNumberOfElementsInLinkedList(log_cache)+1UL,
sizeof(*preferences));
646 if (preferences == (
char **) NULL)
647 return((
char **) NULL);
648 LockSemaphoreInfo(log_semaphore);
649 p=GetHeadElementInLinkedList(log_cache);
650 for (i=0; p != (ElementInfo *) NULL; )
655 log_info=(
const LogInfo *) p->value;
656 if ((log_info->stealth == MagickFalse) &&
657 (GlobExpression(log_info->name,pattern,MagickFalse) != MagickFalse))
658 preferences[i++]=ConstantString(log_info->name);
661 UnlockSemaphoreInfo(log_semaphore);
663 preferences=(
char **) RelinquishMagickMemory(preferences);
666 qsort((
void *) preferences,(
size_t) i,
sizeof(*preferences),LogCompare);
667 preferences[i]=(
char *) NULL;
669 *number_preferences=(size_t) i;
691MagickExport
const char *GetLogName(
void)
720static inline void CheckEventLogging(
void)
725 if (IsLinkedListEmpty(log_cache) != MagickFalse)
726 event_logging=MagickFalse;
732 p=GetHeadElementInLinkedList(log_cache);
733 event_logging=(p != (ElementInfo *) NULL) &&
734 (((LogInfo *) p->value)->event_mask != NoEvents) ?
735 MagickTrue: MagickFalse;
739static MagickBooleanType IsLogCacheInstantiated(ExceptionInfo *exception)
741 if (log_cache == (LinkedListInfo *) NULL)
744 ActivateSemaphoreInfo(&log_semaphore);
745 LockSemaphoreInfo(log_semaphore);
746 if (log_cache == (LinkedListInfo *) NULL)
748 log_cache=AcquireLogCache(LogFilename,exception);
751 UnlockSemaphoreInfo(log_semaphore);
753 return(log_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
775MagickExport MagickBooleanType IsEventLogging(
void)
777 return(event_logging);
804MagickExport MagickBooleanType ListLogInfo(FILE *file,ExceptionInfo *exception)
806#define MegabytesToBytes(value) ((MagickSizeType) (value)*1024*1024)
823 if (file == (
const FILE *) NULL)
825 log_info=GetLogInfoList(
"*",&number_aliases,exception);
826 if (log_info == (
const LogInfo **) NULL)
829 path=(
const char *) NULL;
830 for (i=0; i < (ssize_t) number_aliases; i++)
833 limit[MagickPathExtent];
835 if (log_info[i]->stealth != MagickFalse)
837 if ((path == (
const char *) NULL) ||
838 (LocaleCompare(path,log_info[i]->path) != 0))
840 if (log_info[i]->path != (
char *) NULL)
841 (void) FormatLocaleFile(file,
"\nPath: %s\nHandler: ",
843 for (j=0; j < (ssize_t) (8*
sizeof(LogHandlerType)); j++)
848 if (*LogHandlers[j].name ==
'\0')
852 if (((
size_t) log_info[i]->handler_mask & mask) != 0)
853 (void) FormatLocaleFile(file,
"%s ",LogHandlers[j].name);
855 (void) FormatLocaleFile(file,
"\n\n");
857 (void) FormatLocaleFile(file,
858 "Generations Limit Filename\n");
859 (void) FormatLocaleFile(file,
"---------------------------------------------"
860 "----------------------------------\n");
861 (void) FormatLocaleFile(file,
"%g ",(
double) log_info[i]->generations);
862 (void) CopyMagickString(limit,
"unlimited",MagickPathExtent);
863 if (log_info[i]->limit > 0)
864 (void) FormatMagickSize(log_info[i]->limit,MagickTrue,
"B",
865 MagickFormatExtent,limit);
866 (void) FormatLocaleFile(file,
" %9s",limit);
867 if (log_info[i]->filename != (
char *) NULL)
868 (void) FormatLocaleFile(file,
" %s",log_info[i]->filename);
869 (void) FormatLocaleFile(file,
"\n");
870 if (log_info[i]->format != (
char *) NULL)
871 (void) FormatLocaleFile(file,
" Format: %s\n",log_info[i]->format);
872 (void) FormatLocaleFile(file,
"\n");
873 path=log_info[i]->path;
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],
922 *log_info = (LogInfo *) NULL;
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)
956 for ( ; *q !=
'\0'; q++)
965 if ((*q ==
'"') || (*q ==
'\''))
973 if (bracket_depth > 0)
977 if ((*q ==
'>') && (bracket_depth == 0))
985 if (LocaleNCompare(keyword,
"<!--",4) == 0)
990 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
991 (void) GetNextToken(q,&q,extent,token);
994 if (LocaleCompare(keyword,
"<include") == 0)
999 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1001 (void) CopyMagickString(keyword,token,MagickPathExtent);
1002 (void) GetNextToken(q,&q,extent,token);
1005 (void) GetNextToken(q,&q,extent,token);
1006 if (LocaleCompare(keyword,
"file") == 0)
1008 if (depth > MagickMaxRecursionDepth)
1009 (void) ThrowMagickException(exception,GetMagickModule(),
1010 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1014 path[MagickPathExtent],
1017 GetPathComponent(filename,HeadPath,path);
1019 (void) ConcatenateMagickString(path,DirectorySeparator,
1021 if (*token == *DirectorySeparator)
1022 (void) CopyMagickString(path,token,MagickPathExtent);
1024 (
void) ConcatenateMagickString(path,token,MagickPathExtent);
1025 file_xml=FileToXML(path,~0UL);
1026 if (file_xml != (
char *) NULL)
1028 status&=(MagickStatusType) LoadLogCache(cache,file_xml,
1029 path,depth+1,exception);
1030 file_xml=DestroyString(file_xml);
1037 if (LocaleCompare(keyword,
"<logmap>") == 0)
1042 log_info=(LogInfo *) AcquireCriticalMemory(
sizeof(*log_info));
1043 (void) memset(log_info,0,
sizeof(*log_info));
1044 log_info->path=ConstantString(filename);
1045 GetTimerInfo((TimerInfo *) &log_info->timer);
1046 log_info->signature=MagickCoreSignature;
1049 if (log_info == (LogInfo *) NULL)
1051 if (LocaleCompare(keyword,
"</logmap>") == 0)
1053 status=AppendValueToLinkedList(cache,log_info);
1054 if (status == MagickFalse)
1055 (void) ThrowMagickException(exception,GetMagickModule(),
1056 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",filename);
1057 log_info=(LogInfo *) NULL;
1060 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1063 (void) GetNextToken(q,&q,extent,token);
1064 (void) GetNextToken(q,&q,extent,token);
1070 if (LocaleCompare((
char *) keyword,
"events") == 0)
1072 log_info->event_mask=(LogEventType) (log_info->event_mask |
1073 ParseCommandOption(MagickLogEventOptions,MagickTrue,token));
1081 if (LocaleCompare((
char *) keyword,
"filename") == 0)
1083 if (log_info->filename != (
char *) NULL)
1084 log_info->filename=(
char *)
1085 RelinquishMagickMemory(log_info->filename);
1086 log_info->filename=ConstantString(token);
1089 if (LocaleCompare((
char *) keyword,
"format") == 0)
1091 if (log_info->format != (
char *) NULL)
1092 log_info->format=(
char *)
1093 RelinquishMagickMemory(log_info->format);
1094 log_info->format=ConstantString(token);
1102 if (LocaleCompare((
char *) keyword,
"generations") == 0)
1104 if (LocaleCompare(token,
"unlimited") == 0)
1106 log_info->generations=(~0UL);
1109 log_info->generations=StringToUnsignedLong(token);
1117 if (LocaleCompare((
char *) keyword,
"limit") == 0)
1119 if (LocaleCompare(token,
"unlimited") == 0)
1121 log_info->limit=(~0UL);
1124 log_info->limit=StringToMagickSizeType(token,100.0);
1125 if (log_info->limit < 1024)
1126 log_info->limit=1024*1024*StringToUnsignedLong(token);
1134 if (LocaleCompare((
char *) keyword,
"output") == 0)
1136 log_info->handler_mask=(LogHandlerType)
1137 (log_info->handler_mask | ParseLogHandlers(token));
1146 token=DestroyString(token);
1147 if (cache == (LinkedListInfo *) NULL)
1148 return(MagickFalse);
1149 return(status != 0 ? MagickTrue : MagickFalse);
1171MagickPrivate MagickBooleanType LogComponentGenesis(
void)
1177 log_semaphore=AcquireSemaphoreInfo();
1178 exception=AcquireExceptionInfo();
1179 (void) GetLogInfo(
"*",exception);
1180 exception=DestroyExceptionInfo(exception);
1203static void *DestroyLogElement(
void *log_info)
1208 p=(LogInfo *) log_info;
1209 if (p->file != (FILE *) NULL)
1211 (void) FormatLocaleFile(p->file,
"</log>\n");
1212 (void) fclose(p->file);
1213 p->file=(FILE *) NULL;
1215 if (p->format != (
char *) NULL)
1216 p->format=DestroyString(p->format);
1217 if (p->path != (
char *) NULL)
1218 p->path=DestroyString(p->path);
1219 if (p->filename != (
char *) NULL)
1220 p->filename=DestroyString(p->filename);
1222 RelinquishSemaphoreInfo(&p->event_semaphore);
1223 p=(LogInfo *) RelinquishMagickMemory(p);
1224 return((
void *) NULL);
1227MagickPrivate
void LogComponentTerminus(
void)
1230 ActivateSemaphoreInfo(&log_semaphore);
1231 LockSemaphoreInfo(log_semaphore);
1232 if (log_cache != (LinkedListInfo *) NULL)
1233 log_cache=DestroyLinkedList(log_cache,DestroyLogElement);
1234 event_logging=MagickFalse;
1235 UnlockSemaphoreInfo(log_semaphore);
1236 RelinquishSemaphoreInfo(&log_semaphore);
1273static void FormatLogFilename(
const LogInfo *log_info,
const ssize_t generation,
1285 assert(log_info != (LogInfo *) NULL);
1287 for (p=log_info->filename; *p !=
'\0'; p++)
1316 q+=(ptrdiff_t) CopyMagickString(q,GetClientName(),MagickPathExtent);
1321 if (log_info->generations == 0)
1323 (void) CopyMagickString(q,
"0",MagickPathExtent);
1327 q+=(ptrdiff_t) FormatLocaleString(q,MagickPathExtent,
"%.17g",(
double)
1328 (generation % log_info->generations));
1333 q+=(ptrdiff_t) CopyMagickString(q,GetLogName(),MagickPathExtent);
1338 q+=(ptrdiff_t) FormatLocaleString(q,MagickPathExtent,
"%.17g",(
double)
1344 q+=(ptrdiff_t) CopyMagickString(q,MagickLibVersionText,
1364static char *TranslateEvent(
const char *module,
const char *function,
1365 const size_t line,
const char *domain,
const char *event)
1392 exception=AcquireExceptionInfo();
1393 log_info=GetLogInfo(
"*",exception);
1394 exception=DestroyExceptionInfo(exception);
1395 text=AcquireString(event);
1396 if (log_info == (LogInfo *) NULL)
1398 seconds=GetMagickTime();
1399 elapsed_time=GetElapsedTime(&log_info->timer);
1400 user_time=GetUserTime(&log_info->timer);
1401 if (log_info->format == (
char *) NULL)
1403 extent=strlen(event)+MagickPathExtent;
1404 if (LocaleCompare(log_info->format,
"xml") == 0)
1407 timestamp[MagickTimeExtent];
1412 (void) FormatMagickTime(seconds,
sizeof(timestamp),timestamp);
1413 (void) FormatLocaleString(text,extent,
1415 " <timestamp>%s</timestamp>\n"
1416 " <elapsed-time>%lu:%02lu.%06lu</elapsed-time>\n"
1417 " <user-time>%0.3f</user-time>\n"
1418 " <process-id>%.17g</process-id>\n"
1419 " <thread-id>%.17g</thread-id>\n"
1420 " <module>%s</module>\n"
1421 " <function>%s</function>\n"
1422 " <line>%.17g</line>\n"
1423 " <domain>%s</domain>\n"
1424 " <event>%s</event>\n"
1425 "</entry>",timestamp,(
unsigned long) (elapsed_time/60.0),
1426 (
unsigned long) floor(fmod(elapsed_time,60.0)),(
unsigned long)
1427 (1000000.0*(elapsed_time-floor(elapsed_time))+0.5),user_time,
1428 (
double) getpid(),(
double) GetMagickThreadSignature(),module,function,
1429 (
double) line,domain,event);
1436 for (p=log_info->format; *p !=
'\0'; p++)
1439 if ((
size_t) (q-text+MagickPathExtent) >= extent)
1442 text=(
char *) ResizeQuantumMemory(text,extent,
sizeof(*text));
1443 if (text == (
char *) NULL)
1444 return((
char *) NULL);
1445 q=text+strlen(text);
1467 if ((*p ==
'\\') && (*(p+1) ==
'r'))
1473 if ((*p ==
'\\') && (*(p+1) ==
'n'))
1491 q+=(ptrdiff_t) CopyMagickString(q,GetClientName(),extent-(q-text));
1496 q+=(ptrdiff_t) CopyMagickString(q,domain,extent-(q-text));
1501 q+=(ptrdiff_t) CopyMagickString(q,event,extent-(q-text));
1506 q+=(ptrdiff_t) CopyMagickString(q,function,extent-(q-text));
1511 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%.17g",(
double)
1512 GetMagickThreadSignature());
1517 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%.17g",(
double)
1526 for (r=module+strlen(module)-1; r > module; r--)
1527 if (*r == *DirectorySeparator)
1532 q+=(ptrdiff_t) CopyMagickString(q,r,extent-(q-text));
1537 q+=(ptrdiff_t) CopyMagickString(q,GetLogName(),extent-(q-text));
1542 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%.17g",(
double)
1548 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%lu:%02lu.%03lu",
1549 (
unsigned long) (elapsed_time/60.0),(
unsigned long) floor(fmod(
1550 elapsed_time,60.0)),(
unsigned long) (1000.0*(elapsed_time-floor(
1551 elapsed_time))+0.5));
1556 q+=(ptrdiff_t) FormatMagickTime(seconds,extent-(q-text),q);
1561 q+=(ptrdiff_t) FormatLocaleString(q,extent-(q-text),
"%0.3fu",user_time);
1566 q+=(ptrdiff_t) CopyMagickString(q,MagickLibVersionText,extent-(q-text));
1586MagickExport MagickBooleanType LogMagickEventList(
const LogEventType type,
1587 const char *module,
const char *function,
const size_t line,
const char *format,
1591 event[MagickPathExtent],
1606 exception=AcquireExceptionInfo();
1607 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1608 exception=DestroyExceptionInfo(exception);
1609 if (log_info == (LogInfo *) NULL)
1610 return(MagickFalse);
1612 ActivateSemaphoreInfo(&log_info->event_semaphore);
1613 LockSemaphoreInfo(log_info->event_semaphore);
1614 if ((log_info->event_mask & type) == 0)
1616 UnlockSemaphoreInfo(log_info->event_semaphore);
1619 domain=CommandOptionToMnemonic(MagickLogEventOptions,type);
1620 n=vsnprintf(event,MagickPathExtent,format,operands);
1622 event[MagickPathExtent-1]=
'\0';
1623 text=TranslateEvent(module,function,line,domain,event);
1624 if (text == (
char *) NULL)
1626 (void) ContinueTimer((TimerInfo *) &log_info->timer);
1627 UnlockSemaphoreInfo(log_info->event_semaphore);
1628 return(MagickFalse);
1630 if ((log_info->handler_mask & ConsoleHandler) != 0)
1632 (void) FormatLocaleFile(stderr,
"%s\n",text);
1633 (void) fflush(stderr);
1635 if ((log_info->handler_mask & DebugHandler) != 0)
1637#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1638 OutputDebugString(text);
1639 OutputDebugString(
"\n");
1642 if ((log_info->handler_mask & EventHandler) != 0)
1644#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1645 (void) NTReportEvent(text,MagickFalse);
1648 if ((log_info->handler_mask & FileHandler) != 0)
1653 file_info.st_size=0;
1654 if (log_info->file != (FILE *) NULL)
1655 (void) fstat(fileno(log_info->file),&file_info);
1656 if (file_info.st_size > (MagickOffsetType) log_info->limit)
1664 (void) FormatLocaleFile(log_info->file,
"</log>\n");
1665 (void) FormatLocaleFile(log_info->file,
"</logEntries>\n");
1666 (void) fclose(log_info->file);
1667 for (i=(ssize_t) log_info->generations-1; i > 0; i--)
1670 new_filename[MagickPathExtent],
1671 old_filename[MagickPathExtent];
1676 FormatLogFilename(log_info,i-1,old_filename);
1677 FormatLogFilename(log_info,i,new_filename);
1678 (void) rename_utf8(old_filename,new_filename);
1680 log_info->file=(FILE *) NULL;
1682 if (log_info->file == (FILE *) NULL)
1685 log_filename[MagickPathExtent];
1687 FormatLogFilename(log_info,0,log_filename);
1688 log_info->append=IsPathAccessible(log_filename);
1689 log_info->file=fopen_utf8(log_filename,
"ab");
1690 if (log_info->file == (FILE *) NULL)
1692 UnlockSemaphoreInfo(log_info->event_semaphore);
1693 return(MagickFalse);
1695 if (log_info->append == MagickFalse)
1697 (void) FormatLocaleFile(log_info->file,
"<?xml version=\"1.0\" "
1698 "encoding=\"UTF-8\" standalone=\"yes\"?>\n");
1699 (void) FormatLocaleFile(log_info->file,
"<logEntries>\n");
1701 (void) FormatLocaleFile(log_info->file,
"<log>\n");
1703 (void) FormatLocaleFile(log_info->file,
" <event>%s</event>\n",text);
1704 (void) fflush(log_info->file);
1706 if ((log_info->handler_mask & MethodHandler) != 0)
1708 if (log_info->method != (MagickLogMethod) NULL)
1709 log_info->method(type,text);
1711 if ((log_info->handler_mask & StdoutHandler) != 0)
1713 (void) FormatLocaleFile(stdout,
"%s\n",text);
1714 (void) fflush(stdout);
1716 if ((log_info->handler_mask & StderrHandler) != 0)
1718 (void) FormatLocaleFile(stderr,
"%s\n",text);
1719 (void) fflush(stderr);
1721 text=(
char *) RelinquishMagickMemory(text);
1722 (void) ContinueTimer((TimerInfo *) &log_info->timer);
1723 UnlockSemaphoreInfo(log_info->event_semaphore);
1727MagickExport MagickBooleanType LogMagickEvent(
const LogEventType type,
1728 const char *module,
const char *function,
const size_t line,
1729 const char *format,...)
1737 if (IsEventLogging() == MagickFalse)
1738 return(MagickFalse);
1739 va_start(operands,format);
1740 status=LogMagickEventList(type,module,function,line,format,operands);
1745#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
1769static LogHandlerType ParseLogHandlers(
const char *handlers)
1783 handler_mask=NoHandler;
1784 for (p=handlers; p != (
char *) NULL; p=strchr(p,
','))
1786 while ((*p !=
'\0') && ((isspace((
int) ((
unsigned char) *p)) != 0) ||
1789 for (i=0; *LogHandlers[i].name !=
'\0'; i++)
1791 length=strlen(LogHandlers[i].name);
1792 if (LocaleNCompare(p,LogHandlers[i].name,length) == 0)
1794 handler_mask=(LogHandlerType) (handler_mask | LogHandlers[i].handler);
1798 if (*LogHandlers[i].name ==
'\0')
1799 return(UndefinedHandler);
1801 return(handler_mask);
1829MagickExport LogEventType SetLogEventMask(
const char *events)
1843 event_mask=UndefinedEvents;
1844 exception=AcquireExceptionInfo();
1845 log_info=GetLogInfo(
"*",exception);
1846 exception=DestroyExceptionInfo(exception);
1847 if (log_info == (LogInfo *) NULL)
1849 option=ParseCommandOption(MagickLogEventOptions,MagickTrue,events);
1850 LockSemaphoreInfo(log_semaphore);
1851 event_mask=log_info->event_mask;
1853 log_info->event_mask=UndefinedEvents;
1855 log_info->event_mask=(LogEventType) option;
1856 CheckEventLogging();
1857 UnlockSemaphoreInfo(log_semaphore);
1883MagickExport
void SetLogFormat(
const char *format)
1891 exception=AcquireExceptionInfo();
1892 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1893 exception=DestroyExceptionInfo(exception);
1894 if (log_info == (LogInfo *) NULL)
1896 LockSemaphoreInfo(log_semaphore);
1897 if (log_info->format != (
char *) NULL)
1898 log_info->format=DestroyString(log_info->format);
1899 log_info->format=ConstantString(format);
1900 UnlockSemaphoreInfo(log_semaphore);
1926MagickExport
void SetLogMethod(MagickLogMethod method)
1934 exception=AcquireExceptionInfo();
1935 log_info=(LogInfo *) GetLogInfo(
"*",exception);
1936 exception=DestroyExceptionInfo(exception);
1937 if (log_info == (LogInfo *) NULL)
1939 LockSemaphoreInfo(log_semaphore);
1940 log_info=(LogInfo *) GetValueFromLinkedList(log_cache,0);
1941 log_info->handler_mask=(LogHandlerType) (log_info->handler_mask |
1943 log_info->method=method;
1944 UnlockSemaphoreInfo(log_semaphore);
1971MagickExport
const char *SetLogName(
const char *name)
1973 if ((name != (
char *) NULL) && (*name !=
'\0'))
1974 (void) CopyMagickString(log_name,name,MagickPathExtent);