2 * This file Copyright (C) 2010-2014 Mnemosyne LLC
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
7 * $Id: utils.c 13863 2013-01-24 23:59:52Z jordan $
13 #include <stdlib.h> /* getenv() */
15 #include <event2/buffer.h>
17 #include "transmission.h"
19 #include "platform.h" /* tr_lock */
22 tr_log_level __tr_message_level
= TR_LOG_ERROR
;
24 static bool myQueueEnabled
= false;
25 static tr_log_message
* myQueue
= NULL
;
26 static tr_log_message
** myQueueTail
= &myQueue
;
27 static int myQueueLength
= 0;
30 /* make null versions of these win32 functions */
31 static inline int IsDebuggerPresent (void) { return false; }
32 static inline void OutputDebugStringA (const void * unused UNUSED
) { }
42 return __tr_message_level
;
52 static tr_lock
* l
= NULL
;
63 static bool initialized
= false;
64 static FILE * file
= NULL
;
69 const char * str
= getenv ("TR_DEBUG_FD");
96 tr_logSetLevel (tr_log_level level
)
98 __tr_message_level
= level
;
102 tr_logSetQueueEnabled (bool isEnabled
)
104 assert (tr_isBool (isEnabled
));
106 myQueueEnabled
= isEnabled
;
110 tr_logGetQueueEnabled (void)
112 return myQueueEnabled
;
116 tr_logGetQueue (void)
118 tr_log_message
* ret
;
119 tr_lockLock (getMessageLock ());
123 myQueueTail
= &myQueue
;
126 tr_lockUnlock (getMessageLock ());
131 tr_logFreeQueue (tr_log_message
* list
)
133 tr_log_message
* next
;
138 free (list
->message
);
150 tr_logGetTimeStr (char * buf
, int buflen
)
158 tr_gettimeofday (&tv
);
161 tr_localtime_r (&seconds
, &now_tm
);
162 strftime (tmp
, sizeof (tmp
), "%Y-%m-%d %H:%M:%S.%%03d %Z", &now_tm
);
163 milliseconds
= tv
.tv_usec
/ 1000;
164 tr_snprintf (buf
, buflen
, tmp
, milliseconds
);
170 tr_logGetDeepEnabled (void)
172 static int8_t deepLoggingIsActive
= -1;
174 if (deepLoggingIsActive
< 0)
175 deepLoggingIsActive
= IsDebuggerPresent () || (tr_logGetFile ()!=NULL
);
177 return deepLoggingIsActive
!= 0;
181 tr_logAddDeep (const char * file
,
187 FILE * fp
= tr_logGetFile ();
188 if (fp
|| IsDebuggerPresent ())
193 struct evbuffer
* buf
= evbuffer_new ();
194 char * base
= tr_basename (file
);
196 evbuffer_add_printf (buf
, "[%s] ",
197 tr_logGetTimeStr (timestr
, sizeof (timestr
)));
199 evbuffer_add_printf (buf
, "%s ", name
);
200 va_start (args
, fmt
);
201 evbuffer_add_vprintf (buf
, fmt
, args
);
203 evbuffer_add_printf (buf
, " (%s:%d)\n", base
, line
);
204 /* FIXME (libevent2) ifdef this out for nonwindows platforms */
205 message
= evbuffer_free_to_str (buf
);
206 OutputDebugStringA (message
);
220 tr_logAddMessage (const char * file
,
227 const int err
= errno
; /* message logging shouldn't affect errno */
230 tr_lockLock (getMessageLock ());
232 /* build the text message */
235 evutil_vsnprintf (buf
, sizeof (buf
), fmt
, ap
);
238 OutputDebugStringA (buf
);
242 if (tr_logGetQueueEnabled ())
244 tr_log_message
* newmsg
;
245 newmsg
= tr_new0 (tr_log_message
, 1);
246 newmsg
->level
= level
;
247 newmsg
->when
= tr_time ();
248 newmsg
->message
= tr_strdup (buf
);
251 newmsg
->name
= tr_strdup (name
);
253 *myQueueTail
= newmsg
;
254 myQueueTail
= &newmsg
->next
;
257 if (myQueueLength
> TR_LOG_MAX_QUEUE_LENGTH
)
259 tr_log_message
* old
= myQueue
;
262 tr_logFreeQueue (old
);
264 assert (myQueueLength
== TR_LOG_MAX_QUEUE_LENGTH
);
272 fp
= tr_logGetFile ();
276 tr_logGetTimeStr (timestr
, sizeof (timestr
));
279 fprintf (fp
, "[%s] %s: %s\n", timestr
, name
, buf
);
281 fprintf (fp
, "[%s] %s\n", timestr
, buf
);
286 tr_lockUnlock (getMessageLock ());