| 102 | extern int stat_mainlog_peaklevel; |
| 103 | |
| 104 | int logworkerthread(void *nop) |
| 105 | { |
| 106 | string tmp; |
| 107 | for(;;) |
| 108 | { |
| 109 | while(mainlog.empty()) mainlogsem.wait(); |
| 110 | int mainloglevel = (100 * mainlog.length()) / mainlog.maxsize(); |
| 111 | if(mainloglevel > stat_mainlog_peaklevel) stat_mainlog_peaklevel = mainloglevel; |
| 112 | logline_s *ll = mainlog.remove(); |
| 113 | int targets = loglevelenabled[ll->level]; |
| 114 | bool logtocon = (targets & LOGTARGET_CONSOLE) != 0, logtofile = fp && (targets & LOGTARGET_FILE) != 0, logtosyslog = (targets & LOGTARGET_SYSLOG) != 0; |
| 115 | const char *ts = timestamp ? timestring(ll->t, true, "%b %d %H:%M:%S ", tmp) : "", *ld = levelprefix[ll->level]; |
| 116 | char *p, *l = ll->msg; |
| 117 | do |
| 118 | { // break into single lines first |
| 119 | if((p = strchr(l, '\n'))) *p = '\0'; |
| 120 | if(logtocon) printf("%s%s%s\n", ts, ld, l); |
| 121 | if(logtofile) fprintf(fp, "%s%s%s\n", ts, ld, l); |
| 122 | if(logtosyslog) |
| 123 | #ifdef AC_USE_SYSLOG |
| 124 | syslog(levels[ll->level], "%s", l); |
| 125 | #else |
| 126 | { |
| 127 | defformatstring(text)("<%d>%s: %s", (16 + facility) * 8 + levels[ll->level], ident, l); // no TIMESTAMP, no hostname: syslog will add this |
| 128 | ENetBuffer buf; |
| 129 | buf.data = text; |
| 130 | buf.dataLength = strlen(text); |
| 131 | enet_socket_send(logsock, &logdest, &buf, 1); |
| 132 | } |
| 133 | #endif |
| 134 | l = p + 1; |
| 135 | } |
| 136 | while(p); |
| 137 | #ifdef _DEBUG |
| 138 | if(logtocon) fflush(stdout); |
| 139 | if(logtofile) fflush(fp); |
| 140 | #endif |
| 141 | delete ll; |
| 142 | } |
| 143 | return 0; |
| 144 | } |
| 145 | |
| 146 | void mlog(int level, const char *msg, ...) // log line from main thread (never blocks) |
| 147 | { |
nothing calls this directly
no test coverage detected