3 /* layout_simple - a dumb log layout */
5 /* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved. */
7 /* This program is free software; you can redistribute it and/or modify it
8 * under the terms of the license (GNU LGPL) which comes with this package. */
10 #include "portable.h" /* execinfo when available */
11 #include "xbt/sysdep.h"
13 #include "gras/virtu.h" /* gras_os_myname (KILLME) */
14 #include "xbt/synchro.h" /* xbt_thread_self_name */
17 extern const char *xbt_log_priority_names[7];
19 /* Get serious about checking buffer overflows during log construction */
20 #define check_overflow \
21 if (p-ev->buffer > XBT_LOG_BUFF_SIZE) { /* buffer overflow */ \
22 p=ev->buffer + XBT_LOG_BUFF_SIZE - strlen(" >> OUTPUT TRUNCATED <<\n"); \
23 p+=sprintf(p," >> OUTPUT TRUNCATED <<\n"); \
27 static void xbt_log_layout_format_doit(xbt_log_layout_t l,
29 const char *msg_fmt) {
30 static double begin_of_time = -1;
35 begin_of_time=gras_os_time();
46 fprintf(stderr,"Layout format (%s) ending with %%\n",(char*)l->data);
51 case 'n': /* platform-dependant line separator (LOG4J compliant) */
52 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"\n");
55 case 'e': /* plain space (SimGrid extension) */
56 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer)," ");
60 case '.': /* precision specifyier */
62 q += sscanf(q,"%d",&precision);
65 case 'c': /* category name; LOG4J compliant
66 should accept a precision postfix to show the hierarchy */
67 if (precision == -1) {
68 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"%s",ev->cat->name);
71 p += sprintf(p,"%.*s",(int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision),ev->cat->name);
76 case 'p': /* priority name; LOG4J compliant */
77 if (precision == -1) {
78 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%s", xbt_log_priority_names[ev->priority] );
81 p += sprintf(p, "%.*s", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), xbt_log_priority_names[ev->priority] );
87 case 'h': /* host name; SimGrid extension */
88 if (precision == -1) {
89 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%s", gras_os_myname());
92 p += sprintf(p, "%.*s", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), gras_os_myname());
97 case 't': /* thread name; LOG4J compliant */
98 if (precision == -1) {
99 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%s", xbt_thread_self_name());
102 p += sprintf(p, "%.*s", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), xbt_thread_self_name());
107 case 'P': /* process name; SimGrid extension */
108 if (precision == -1) {
109 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%s", xbt_procname());
112 p += sprintf(p, "%.*s", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision),xbt_procname());
117 case 'i': /* process PID name; SimGrid extension */
118 if (precision == -1) {
119 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%d", (*xbt_getpid)());
122 p += sprintf(p, "%.*d", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), (*xbt_getpid)());
128 case 'F': /* file name; LOG4J compliant */
129 if (precision == -1) {
130 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"%s",ev->fileName);
133 p += sprintf(p,"%.*s",(int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), ev->fileName);
138 case 'l': /* location; LOG4J compliant */
139 if (precision == -1) {
140 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%s:%d", ev->fileName, ev->lineNum);
143 p += snprintf(p, (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), "%s:%d", ev->fileName, ev->lineNum);
148 case 'L': /* line number; LOG4J compliant */
149 if (precision == -1) {
150 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%d", ev->lineNum);
153 p += sprintf(p, "%.*d", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), ev->lineNum);
158 case 'M': /* method (ie, function) name; LOG4J compliant */
159 if (precision == -1) {
160 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), "%s", ev->functionName);
163 p += sprintf(p, "%.*s", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), ev->functionName);
168 case 'b': /* backtrace; called %throwable in LOG4J */
169 case 'B': /* short backtrace; called %throwable{short} in LOG4J */
170 #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
175 e.used = backtrace((void**)e.bt,XBT_BACKTRACE_SIZE);
179 xbt_backtrace_current(&e);
181 if (precision == -1) {
182 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"%s",e.bt_strings[2]+8);
185 p += sprintf(p,"%.*s",(int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), e.bt_strings[2]+8);
190 for (i=2; i<e.used; i++)
191 if (precision == -1) {
192 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"%s\n",e.bt_strings[i]+8);
195 p += sprintf(p,"%.*s\n",(int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision),e.bt_strings[i]+8);
204 p+=snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"(no backtrace on this arch)");
209 case 'd': /* date; LOG4J compliant */
210 if (precision == -1) {
211 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"%f", gras_os_time());
214 p += sprintf(p,"%.*f", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), gras_os_time());
219 case 'r': /* application age; LOG4J compliant */
220 if (precision == -1) {
221 p += snprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer),"%f", gras_os_time()-begin_of_time);
224 p += sprintf(p,"%.*f", (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), gras_os_time()-begin_of_time);
230 case 'm': /* user-provided message; LOG4J compliant */
231 if (precision == -1) {
232 p += vsnprintf(p,XBT_LOG_BUFF_SIZE-(p-ev->buffer), msg_fmt, ev->ap);
235 p += vsnprintf(p, (int)MIN(XBT_LOG_BUFF_SIZE-(p-ev->buffer),precision), msg_fmt, ev->ap);
242 fprintf(stderr,"Unknown %%%c sequence in layout format (%s)\n",
254 static void xbt_log_layout_format_free(xbt_log_layout_t lay) {
257 xbt_log_layout_t xbt_log_layout_format_new(char *arg) {
258 xbt_log_layout_t res = xbt_new0(s_xbt_log_layout_t,1);
259 res->do_layout = xbt_log_layout_format_doit;
260 res->free_ = xbt_log_layout_format_free;
261 res->data = xbt_strdup((char*)arg);