diem_logger/
metadata.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8use serde::{Deserialize, Serialize};
9use std::{fmt, str::FromStr};
10
11/// Associated metadata with every log to identify what kind of log and where it
12/// came from
13#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
14pub struct Metadata {
15    /// The level of verbosity of the event
16    level: Level,
17
18    /// The part of the system where the event occurred
19    target: &'static str,
20
21    /// The name of the Rust module where the event occurred
22    module_path: &'static str,
23
24    /// The name of the source code file where the event occurred
25    file: &'static str,
26
27    /// The line number in the source code file where the event occurred
28    line: u32,
29
30    /// The file name and line number together 'file:line'
31    location: &'static str,
32}
33
34impl Metadata {
35    pub const fn new(
36        level: Level, target: &'static str, module_path: &'static str,
37        file: &'static str, line: u32, location: &'static str,
38    ) -> Self {
39        Self {
40            level,
41            target,
42            module_path,
43            file,
44            line,
45            location,
46        }
47    }
48
49    pub fn enabled(&self) -> bool { crate::logger::enabled(self) }
50
51    pub fn level(&self) -> Level { self.level }
52
53    pub fn target(&self) -> &'static str { self.target }
54
55    pub fn module_path(&self) -> &'static str { self.module_path }
56
57    pub fn file(&self) -> &'static str { self.file }
58
59    pub fn line(&self) -> u32 { self.line }
60
61    pub fn location(&self) -> &'static str { self.location }
62}
63
64static LOG_LEVEL_NAMES: &[&str] = &["ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
65
66/// Logging levels, used for stratifying logs, and disabling less important ones
67/// for performance reasons
68#[repr(usize)]
69#[derive(
70    Copy,
71    Clone,
72    PartialEq,
73    Eq,
74    PartialOrd,
75    Ord,
76    Debug,
77    Hash,
78    Serialize,
79    Deserialize,
80)]
81#[serde(rename_all = "UPPERCASE")]
82pub enum Level {
83    /// The "error" level.
84    ///
85    /// Designates very serious errors.
86    Error = 0,
87    /// The "warn" level.
88    ///
89    /// Designates hazardous situations.
90    Warn,
91    /// The "info" level.
92    ///
93    /// Designates useful information.
94    Info,
95    /// The "debug" level.
96    ///
97    /// Designates lower priority information.
98    Debug,
99    /// The "trace" level.
100    ///
101    /// Designates very low priority, often extremely verbose, information.
102    Trace,
103}
104
105impl Level {
106    fn from_usize(idx: usize) -> Option<Self> {
107        let lvl = match idx {
108            0 => Level::Error,
109            1 => Level::Warn,
110            2 => Level::Info,
111            3 => Level::Debug,
112            4 => Level::Trace,
113            _ => return None,
114        };
115
116        Some(lvl)
117    }
118}
119
120/// An error given when no `Level` matches the inputted string
121#[derive(Debug)]
122pub struct LevelParseError;
123
124impl FromStr for Level {
125    type Err = LevelParseError;
126
127    fn from_str(level: &str) -> Result<Level, Self::Err> {
128        LOG_LEVEL_NAMES
129            .iter()
130            .position(|name| name.eq_ignore_ascii_case(level))
131            .map(|idx| Level::from_usize(idx).unwrap())
132            .ok_or(LevelParseError)
133    }
134}
135
136impl fmt::Display for Level {
137    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
138        fmt.pad(LOG_LEVEL_NAMES[*self as usize])
139    }
140}