about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs33
-rw-r--r--src/tests.rs6
2 files changed, 37 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs
index 0f1f11ddda79..9519b40ce4a2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -339,6 +339,27 @@ fn parse_microseconds(input: String) -> Option<DateTime<Utc>> {
     }
 }
 
+/// Converts a journald log message priority (using levels 0/emerg through
+/// 7/debug, see "man journalctl" and "man systemd.journal-fields") to a
+/// Stackdriver-compatible severity number (see
+/// https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity).
+/// Conveniently, the names are the same. Inconveniently, the numbers are not.
+///
+/// Any unknown values are returned as an empty option.
+fn priority_to_severity(priority: String) -> Option<u32> {
+    match priority.as_ref() {
+        "0" => Some(800), // emerg
+        "1" => Some(700), // alert
+        "2" => Some(600), // crit
+        "3" => Some(500), // err
+        "4" => Some(400), // warning
+        "5" => Some(300), // notice
+        "6" => Some(200), // info
+        "7" => Some(100), // debug
+        _ => None,
+    }
+}
+
 /// This structure represents a log entry in the format expected by
 /// the Stackdriver API.
 #[derive(Debug, Serialize)]
@@ -351,6 +372,10 @@ struct LogEntry {
 
     #[serde(flatten)]
     payload: Payload,
+
+    // https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
+    #[serde(skip_serializing_if = "Option::is_none")]
+    severity: Option<u32>,
 }
 
 impl From<JournalRecord> for LogEntry {
@@ -382,6 +407,13 @@ impl From<JournalRecord> for LogEntry {
             .remove("_SOURCE_REALTIME_TIMESTAMP")
             .and_then(parse_microseconds);
 
+        // Journald uses syslogd's concept of priority. No idea if this is
+        // always present, but it's optional in the Stackdriver API, so we just
+        // omit it if we can't find or parse it.
+        let severity = record
+            .remove("PRIORITY")
+            .and_then(priority_to_severity);
+
         LogEntry {
             payload,
             timestamp,
@@ -389,6 +421,7 @@ impl From<JournalRecord> for LogEntry {
                 "host": hostname,
                 "unit": unit.unwrap_or_else(|| "syslog".into()),
             }),
+            severity,
         }
     }
 }
diff --git a/src/tests.rs b/src/tests.rs
index 1547855299bf..779add7a7012 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -8,7 +8,8 @@ fn test_text_entry_serialization() {
         timestamp: None,
         payload: Payload::TextPayload {
             text_payload: "test entry".into(),
-        }
+        },
+        severity: None,
     };
 
     let expected = "{\"labels\":null,\"textPayload\":\"test entry\"}";
@@ -26,7 +27,8 @@ fn test_json_entry_serialization() {
             json_payload: json!({
                 "message": "JSON test"
             })
-        }
+        },
+        severity: None,
     };
 
     let expected = "{\"labels\":null,\"jsonPayload\":{\"message\":\"JSON test\"}}";