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