; levels, and is enclosed in square brackets. Valid formatters are:
; - [default] - The default formatter, this outputs log messages using a
; human readable format.
+; - [plain] - The plain formatter, this outputs log messages using a
+; human readable format with the addition of function name
+; and line number. No color escape codes are ever printed
+ nor are verbose messages treated specially.
; - [json] - Log the output in JSON. Note that JSON formatted log entries,
; if specified for a logger type of 'console', will be formatted
; per the 'default' formatter for log messages of type VERBOSE.
--- /dev/null
+Subject: logger
+
+Added a new log formatter called "plain" that always prints
+file, function and line number if available (even for verbose
+messages) and never prints color control characters. Most
+suitable for file output but can be used for other channels
+as well.
+
+You use it in logger.conf like so:
+debug => [plain]debug
+console => [plain]error,warning,debug,notice,pjsip_history
+messages => [plain]warning,error,verbose
.format_log = format_log_default,
};
+static int format_log_plain(struct logchannel *chan, struct logmsg *msg, char *buf, size_t size)
+{
+ char call_identifier_str[13];
+ char linestr[32];
+ int has_file = !ast_strlen_zero(msg->file);
+ int has_line = (msg->line > 0);
+ int has_func = !ast_strlen_zero(msg->function);
+
+ if (msg->callid) {
+ snprintf(call_identifier_str, sizeof(call_identifier_str), "[C-%08x]", msg->callid);
+ } else {
+ call_identifier_str[0] = '\0';
+ }
+
+ switch (chan->type) {
+ case LOGTYPE_SYSLOG:
+ snprintf(buf, size, "%s[%d]%s: %s:%d in %s: %s",
+ levels[msg->level], msg->lwp, call_identifier_str, msg->file,
+ msg->line, msg->function, msg->message);
+ term_strip(buf, buf, size);
+ break;
+ case LOGTYPE_FILE:
+ case LOGTYPE_CONSOLE:
+ /* Turn the numerical line number into a string */
+ snprintf(linestr, sizeof(linestr), "%d", msg->line);
+ /* Build string to print out */
+ snprintf(buf, size, "[%s] %s[%d]%s: %s%s%s%s%s%s%s",
+ msg->date,
+ msg->level_name,
+ msg->lwp,
+ call_identifier_str,
+ has_file ? msg->file : "",
+ has_file ? ":" : "",
+ has_line ? linestr : "",
+ has_line ? " " : "",
+ has_func ? msg->function : "",
+ has_func ? ": " : "",
+ msg->message);
+ term_strip(buf, buf, size);
+ break;
+ }
+
+ return 0;
+}
+
+static struct logformatter logformatter_plain = {
+ .name = "plain",
+ .format_log = format_log_plain,
+};
+
static void make_components(struct logchannel *chan)
{
char *w;
memcpy(&chan->formatter, &logformatter_json, sizeof(chan->formatter));
} else if (!strcasecmp(formatter_name, "default")) {
memcpy(&chan->formatter, &logformatter_default, sizeof(chan->formatter));
+ } else if (!strcasecmp(formatter_name, "plain")) {
+ memcpy(&chan->formatter, &logformatter_plain, sizeof(chan->formatter));
} else {
fprintf(stderr, "Logger Warning: Unknown formatter definition %s for %s in logger.conf; using 'default'\n",
formatter_name, chan->filename);