Log using Combined Log Format (commonly found in apache log)
authorsolsTiCe d'Hiver <solstice.dhiver@gmail.com>
Mon, 27 Nov 2017 19:10:02 +0000 (20:10 +0100)
committerEmil Mikulic <emikulic@gmail.com>
Wed, 1 Jul 2020 11:47:26 +0000 (21:47 +1000)
Commonly found in Apache log. It adds 2 fields upon the Common Log
Format (referer and user-agent).

https://en.wikipedia.org/wiki/Common_Log_Format

It is just a matter of reordering what your were already logging with a
new date formatting.

* We are cheating because we always assume HTTP/1.1 as the request
  header.

* We assume the user name is unknown.

darkhttpd.c

index 454c7b0..53363bd 100644 (file)
@@ -1280,9 +1280,22 @@ static void logencode(const char *src, char *dest) {
     dest[j] = '\0';
 }
 
+/* Format [when] as a CLF date format, stored in the specified buffer.  The same
+ * buffer is returned for convenience.
+ */
+#define CLF_DATE_LEN 29 /* strlen("[10/Oct/2000:13:55:36 -0700]")+1 */
+static char *clf_date(char *dest, const time_t when) {
+    time_t when_copy = when;
+    if (strftime(dest, CLF_DATE_LEN,
+                 "[%d/%b/%Y:%H:%M:%S %z]", localtime(&when_copy)) == 0)
+        errx(1, "strftime() failed [%s]", dest);
+    return dest;
+}
+
 /* Add a connection's details to the logfile. */
 static void log_connection(const struct connection *conn) {
-    char *safe_method, *safe_url, *safe_referer, *safe_user_agent;
+    char *safe_method, *safe_url, *safe_referer, *safe_user_agent,
+    dest[CLF_DATE_LEN];
 
     if (logfile == NULL)
         return;
@@ -1307,9 +1320,9 @@ static void log_connection(const struct connection *conn) {
 
 #define use_safe(x) safe_##x ? safe_##x : ""
 
-    fprintf(logfile, "%lu %s \"%s %s\" %d %llu \"%s\" \"%s\"\n",
-        (unsigned long int)now,
+    fprintf(logfile, "%s - - %s \"%s %s HTTP/1.1\" %d %llu \"%s\" \"%s\"\n",
         get_address_text(&conn->client),
+        clf_date(dest, now),
         use_safe(method),
         use_safe(url),
         conn->http_code,