1 /**
2  * Copyright © 2021 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 #include <nlohmann/json.hpp>
18 
19 #include <chrono>
20 #include <cstdint>
21 #include <deque>
22 #include <string>
23 #include <tuple>
24 #include <unordered_map>
25 
26 namespace phosphor::fan::control::json
27 {
28 using json = nlohmann::json;
29 
30 /**
31  * @class FlightRecorder
32  *
33  * This class stores messages and their timestamps based on an ID.
34  * When an ID accumulates so many messages, the oldest one will
35  * be removed when a new one is added.
36  *
37  * The dump() function interleaves the messages for all IDs together
38  * based on timestamp and then writes them all to /tmp/fan_control.txt.
39  *
40  * For example:
41  * Oct 01 04:37:19.122771:           main: Startup
42  * Oct 01 04:37:19.123923: mapped_floor-1: Setting new floor to 4755
43  */
44 class FlightRecorder
45 {
46   public:
47     ~FlightRecorder() = default;
48     FlightRecorder(const FlightRecorder&) = delete;
49     FlightRecorder& operator=(const FlightRecorder&) = delete;
50     FlightRecorder(FlightRecorder&&) = delete;
51     FlightRecorder& operator=(FlightRecorder&&) = delete;
52 
53     /**
54      * @brief Returns a reference to the static instance.
55      */
56     static FlightRecorder& instance();
57 
58     /**
59      * @brief Logs an entry to the recorder.
60      *
61      * @param[in] id - The ID of the message owner
62      * @param[in] message - The message to log
63      */
64     void log(const std::string& id, const std::string& message);
65 
66     /**
67      * @brief Writes the flight recorder contents to JSON.
68      *
69      * Sorts all messages by timestamp when doing so.
70      *
71      * @param[out] data - Filled in with the flight recorder data
72      */
73     void dump(json& data);
74 
75   private:
76     FlightRecorder() = default;
77 
78     // tuple<timestamp, message>
79     using Entry = std::tuple<uint64_t, std::string>;
80 
81     /* The messages */
82     std::unordered_map<std::string, std::deque<Entry>> _entries;
83 };
84 
85 } // namespace phosphor::fan::control::json
86