1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! `Echo Event Format` Data Structures
use serde::{Serialize, Serializer};
use std::collections::HashMap;
use uuid::Uuid;

/// The `type` field that describes the message.
pub enum Type {
    /// Any message that should be associated with a non-normal action or situation that the system processed.
    Error,
    /// Any message that should be associated with a normal action or situation that the system processed.
    Info,
    /// Any message that associates speed or time taken with which any action or situation that the system processed.
    Performance,
    /// Any message that tries to correlate two (or more) events or data points that is not associated.
    Tracking,
    /// Internally used for client machine performance data (CPU utilization, JVM heap usage, ect)
    System,
}

impl Default for Type {
    fn default() -> Self {
        Type::Info
    }
}

impl Serialize for Type {
    fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let type_str = match *self {
            Type::Error => "ERROR",
            Type::Info => "INFO",
            Type::Performance => "PERFORMANCE",
            Type::Tracking => "TRACKING",
            Type::System => "SYSTEM",
        };
        serializer.serialize_str(type_str)
    }
}

#[derive(Default, Serialize, Setters)]
#[serde(rename_all = "camelCase")]
/// The Echo Event Format items.
pub struct Message {
    /// The `routing_key` is what identifies the message with an application.
    /// It will become the ElasticSearch index. Valid characters are lowercase alpha numeric and '-'.
    /// The key should follow the format <application group>-<application name>-<environment>.
    #[set = "pub"]
    routing_key: String,
    /// The message type.
    /// Additional types may be added in the future.
    #[set = "pub"]
    #[serde(rename = "type")]
    level: Type,
    /// A simple string message.  Most messages should be one line of information.
    /// If you have secondary, deeper information to store, put it in the `message_detail`.
    #[set = "pub"]
    message: String,
    /// Hostname where the message originated.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    host: Option<String>,
    /// A place to store custom key/value pairs in the message, typically used when there isn't an appropriate root-level field.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    message_detail: Option<HashMap<String, String>>,
    /// The timestamp of the event.
    ///
    /// If producing your own messages, the format of the date should be either of:
    ///
    /// * An ISO-8601 date/time string (e.g. 2018-04-06T17:23:00-04:00)
    /// * A number representing *milliseconds* since epoch (e.g. 1491514054000).  Note many timestamps are *seconds* since
    /// the epoch.   That is incorrect for this usage.
    #[set = "pub"]
    timestamp: i64,
    /// The UUID that should be used to correlate message that are part of the same request or processing event.
    /// This can be used to correlate events across applications.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    correlation_id: Option<Uuid>,
    /// Sets the version of the application that is creating this message.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    application_version: Option<String>,
    /// The hostname of a client if this message is involving an external system calling into your system.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    client_hostname: Option<String>,
    /// The hostname of a destination system if this message is involving your system calling an external system.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    destination_hostname: Option<String>,
    /// The path being called on a destination system if this message is involving your system calling an external system.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    destination_path: Option<String>,
    /// Sets the start time (timestamp of millis since the epoch) for the time at which this event started.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    start_timestamp: Option<i64>,
    /// Sets the start time (timestamp of millis since the epoch) for the time at which this event finished.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    end_timestamp: Option<i64>,
    /// Sets the duration (time in milliseconds) that passed during this event.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    duration_in_ms: Option<u64>,
    /// The HTTP response code returned by a performance event.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    response_code: Option<u16>,
    /// The size of a request payload, typically associated with performance events.
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    payload_size: Option<u64>,
    /// A more generic response used when a HTTP response code doesn't make sense. Typical values might be "success" or "failure".
    #[set = "pub"]
    #[serde(skip_serializing_if = "Option::is_none")]
    response: Option<String>,
}