xref: /openbmc/phosphor-power/phosphor-regulators/src/journal.hpp (revision 72e584c5bae66b00a55e513dffc410e510348c26)
1 /**
2  * Copyright © 2020 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 
18 #include <systemd/sd-journal.h>
19 
20 #include <phosphor-logging/lg2.hpp>
21 
22 #include <string>
23 #include <vector>
24 
25 namespace phosphor::power::regulators
26 {
27 
28 /**
29  * @class Journal
30  *
31  * Abstract base class that provides a journal interface.
32  *
33  * The interface is used to write messages/log entries to the system journal.
34  */
35 class Journal
36 {
37   public:
38     // Specify which compiler-generated methods we want
39     Journal() = default;
40     Journal(const Journal&) = delete;
41     Journal(Journal&&) = delete;
42     Journal& operator=(const Journal&) = delete;
43     Journal& operator=(Journal&&) = delete;
44     virtual ~Journal() = default;
45 
46     /**
47      * Gets the journal messages that have the specified field set to the
48      * specified value.
49      *
50      * The messages in the returned vector are ordered from oldest to newest.
51      *
52      * @param field journal field name
53      * @param fieldValue expected field value
54      * @param max Maximum number of messages to return.  Specify 0 to return all
55      *            matching messages.
56      * @return matching messages from the journal
57      */
58     virtual std::vector<std::string> getMessages(const std::string& field,
59                                                  const std::string& fieldValue,
60                                                  unsigned int max = 0) = 0;
61 
62     /**
63      * Logs a debug message in the system journal.
64      *
65      * @param message message to log
66      */
67     virtual void logDebug(const std::string& message) = 0;
68 
69     /**
70      * Logs debug messages in the system journal.
71      *
72      * @param messages messages to log
73      */
74     virtual void logDebug(const std::vector<std::string>& messages) = 0;
75 
76     /**
77      * Logs an error message in the system journal.
78      *
79      * @param message message to log
80      */
81     virtual void logError(const std::string& message) = 0;
82 
83     /**
84      * Logs error messages in the system journal.
85      *
86      * @param messages messages to log
87      */
88     virtual void logError(const std::vector<std::string>& messages) = 0;
89 
90     /**
91      * Logs an informational message in the system journal.
92      *
93      * @param message message to log
94      */
95     virtual void logInfo(const std::string& message) = 0;
96 
97     /**
98      * Logs informational messages in the system journal.
99      *
100      * @param messages messages to log
101      */
102     virtual void logInfo(const std::vector<std::string>& messages) = 0;
103 };
104 
105 /**
106  * @class SystemdJournal
107  *
108  * Implementation of the Journal interface that writes to the systemd journal.
109  */
110 class SystemdJournal : public Journal
111 {
112   public:
113     // Specify which compiler-generated methods we want
114     SystemdJournal() = default;
115     SystemdJournal(const SystemdJournal&) = delete;
116     SystemdJournal(SystemdJournal&&) = delete;
117     SystemdJournal& operator=(const SystemdJournal&) = delete;
118     SystemdJournal& operator=(SystemdJournal&&) = delete;
119     virtual ~SystemdJournal() = default;
120 
121     /** @copydoc Journal::getMessages() */
122     virtual std::vector<std::string> getMessages(const std::string& field,
123                                                  const std::string& fieldValue,
124                                                  unsigned int max) override;
125 
126     /** @copydoc Journal::logDebug(const std::string&) */
logDebug(const std::string & message)127     virtual void logDebug(const std::string& message) override
128     {
129         lg2::debug(message.c_str());
130     }
131 
132     /** @copydoc Journal::logDebug(const std::vector<std::string>&) */
logDebug(const std::vector<std::string> & messages)133     virtual void logDebug(const std::vector<std::string>& messages) override
134     {
135         for (const std::string& message : messages)
136         {
137             logDebug(message);
138         }
139     }
140 
141     /** @copydoc Journal::logError(const std::string&) */
logError(const std::string & message)142     virtual void logError(const std::string& message) override
143     {
144         lg2::error(message.c_str());
145     }
146 
147     /** @copydoc Journal::logError(const std::vector<std::string>&) */
logError(const std::vector<std::string> & messages)148     virtual void logError(const std::vector<std::string>& messages) override
149     {
150         for (const std::string& message : messages)
151         {
152             logError(message);
153         }
154     }
155 
156     /** @copydoc Journal::logInfo(const std::string&) */
logInfo(const std::string & message)157     virtual void logInfo(const std::string& message) override
158     {
159         lg2::info(message.c_str());
160     }
161 
162     /** @copydoc Journal::logInfo(const std::vector<std::string>&) */
logInfo(const std::vector<std::string> & messages)163     virtual void logInfo(const std::vector<std::string>& messages) override
164     {
165         for (const std::string& message : messages)
166         {
167             logInfo(message);
168         }
169     }
170 
171   private:
172     /**
173      * Gets the value of the specified field for the current journal entry.
174      *
175      * Returns an empty string if the current journal entry does not have the
176      * specified field.
177      *
178      * @param journal current journal entry
179      * @param field journal field name
180      * @return field value
181      */
182     std::string getFieldValue(sd_journal* journal, const std::string& field);
183 
184     /**
185      * Gets the realtime (wallclock) timestamp for the current journal entry.
186      *
187      * @param journal current journal entry
188      * @return timestamp as a date/time string
189      */
190     std::string getTimeStamp(sd_journal* journal);
191 };
192 
193 } // namespace phosphor::power::regulators
194