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/log.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&) */ 127 virtual void logDebug(const std::string& message) override 128 { 129 using namespace phosphor::logging; 130 log<level::DEBUG>(message.c_str()); 131 } 132 133 /** @copydoc Journal::logDebug(const std::vector<std::string>&) */ 134 virtual void logDebug(const std::vector<std::string>& messages) override 135 { 136 for (const std::string& message : messages) 137 { 138 logDebug(message); 139 } 140 } 141 142 /** @copydoc Journal::logError(const std::string&) */ 143 virtual void logError(const std::string& message) override 144 { 145 using namespace phosphor::logging; 146 log<level::ERR>(message.c_str()); 147 } 148 149 /** @copydoc Journal::logError(const std::vector<std::string>&) */ 150 virtual void logError(const std::vector<std::string>& messages) override 151 { 152 for (const std::string& message : messages) 153 { 154 logError(message); 155 } 156 } 157 158 /** @copydoc Journal::logInfo(const std::string&) */ 159 virtual void logInfo(const std::string& message) override 160 { 161 using namespace phosphor::logging; 162 log<level::INFO>(message.c_str()); 163 } 164 165 /** @copydoc Journal::logInfo(const std::vector<std::string>&) */ 166 virtual void logInfo(const std::vector<std::string>& messages) override 167 { 168 for (const std::string& message : messages) 169 { 170 logInfo(message); 171 } 172 } 173 174 private: 175 /** 176 * Gets the value of the specified field for the current journal entry. 177 * 178 * Returns an empty string if the current journal entry does not have the 179 * specified field. 180 * 181 * @param journal current journal entry 182 * @param field journal field name 183 * @return field value 184 */ 185 std::string getFieldValue(sd_journal* journal, const std::string& field); 186 187 /** 188 * Gets the realtime (wallclock) timestamp for the current journal entry. 189 * 190 * @param journal current journal entry 191 * @return timestamp as a date/time string 192 */ 193 std::string getTimeStamp(sd_journal* journal); 194 }; 195 196 } // namespace phosphor::power::regulators 197