blob: 91206e031ca4b4a6d0fe0e6ab210fa6e62af1f5f [file] [log] [blame]
Adriana Kobylakd311bc82016-10-16 09:54:40 -05001#include <fstream>
2#include <iostream>
Adriana Kobylakc5f0bbd2017-01-22 14:56:04 -06003#include <chrono>
Adriana Kobylakd311bc82016-10-16 09:54:40 -05004#include <cstdio>
5#include <string>
6#include <vector>
Adriana Kobylak1db1bd32016-10-10 11:39:20 -05007#include <sdbusplus/vtable.hpp>
8#include <systemd/sd-bus.h>
Adriana Kobylakd311bc82016-10-16 09:54:40 -05009#include <systemd/sd-journal.h>
Adriana Kobylak7298dc22017-01-24 12:21:50 -060010#include "elog-lookup.cpp"
Saqib Khan2bb15192017-02-13 13:19:55 -060011#include <phosphor-logging/elog-errors-HostEvent.hpp>
Adriana Kobylak4ea7f312017-01-10 12:52:34 -060012#include "config.h"
13#include "elog_entry.hpp"
Saqib Khan2bb15192017-02-13 13:19:55 -060014#include <phosphor-logging/log.hpp>
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060015#include "log_manager.hpp"
Adriana Kobylak1db1bd32016-10-10 11:39:20 -050016
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060017namespace phosphor
18{
19namespace logging
20{
Adriana Kobylakd311bc82016-10-16 09:54:40 -050021
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060022void Manager::commit(uint64_t transactionId, std::string errMsg)
Adriana Kobylak1db1bd32016-10-10 11:39:20 -050023{
Adriana Kobylak7298dc22017-01-24 12:21:50 -060024 constexpr const auto transactionIdVar = "TRANSACTION_ID";
Adriana Kobylak1db1bd32016-10-10 11:39:20 -050025
Adriana Kobylakd311bc82016-10-16 09:54:40 -050026 sd_journal *j = nullptr;
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060027 int rc = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
Adriana Kobylakd311bc82016-10-16 09:54:40 -050028 if (rc < 0)
29 {
30 logging::log<logging::level::ERR>("Failed to open journal",
31 logging::entry("DESCRIPTION=%s", strerror(-rc)));
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060032 return;
Adriana Kobylakd311bc82016-10-16 09:54:40 -050033 }
34
Adriana Kobylak7298dc22017-01-24 12:21:50 -060035 std::string transactionIdStr = std::to_string(transactionId);
36 std::vector<std::string> metalist = g_errMetaMap[errMsg];
Adriana Kobylak1f36a882017-02-16 08:36:55 -060037 std::vector<std::string> metalistHostEvent = g_errMetaMapHostEvent[errMsg];
Adriana Kobylak4ea7f312017-01-10 12:52:34 -060038 std::vector<std::string> additionalData;
Adriana Kobylak7298dc22017-01-24 12:21:50 -060039
Adriana Kobylakd311bc82016-10-16 09:54:40 -050040 // Read the journal from the end to get the most recent entry first.
41 // The result from the sd_journal_get_data() is of the form VARIABLE=value.
42 SD_JOURNAL_FOREACH_BACKWARDS(j)
43 {
44 const char *data = nullptr;
45 size_t length = 0;
46
Adriana Kobylak7298dc22017-01-24 12:21:50 -060047 // Look for the transaction id metadata variable
48 rc = sd_journal_get_data(j, transactionIdVar, (const void **)&data,
49 &length);
Adriana Kobylakd311bc82016-10-16 09:54:40 -050050 if (rc < 0)
51 {
Adriana Kobylak7298dc22017-01-24 12:21:50 -060052 // This journal entry does not have the transaction id,
53 // continue to next entry
Adriana Kobylakd311bc82016-10-16 09:54:40 -050054 continue;
55 }
Adriana Kobylak7298dc22017-01-24 12:21:50 -060056
Adriana Kobylakd311bc82016-10-16 09:54:40 -050057 std::string result(data);
Adriana Kobylak7298dc22017-01-24 12:21:50 -060058 if (result.find(transactionIdStr) == std::string::npos)
Adriana Kobylakd311bc82016-10-16 09:54:40 -050059 {
Adriana Kobylak7298dc22017-01-24 12:21:50 -060060 // Requested transaction id not found,
61 // continue to next journal entry.
Adriana Kobylakd311bc82016-10-16 09:54:40 -050062 continue;
63 }
Adriana Kobylakd311bc82016-10-16 09:54:40 -050064
65 // Search for the metadata variables in the current journal entry
Adriana Kobylak7298dc22017-01-24 12:21:50 -060066 for (auto metaVarStr : metalist)
Adriana Kobylakd311bc82016-10-16 09:54:40 -050067 {
Adriana Kobylak7298dc22017-01-24 12:21:50 -060068 rc = sd_journal_get_data(j, metaVarStr.c_str(),
69 (const void **)&data, &length);
Adriana Kobylakd311bc82016-10-16 09:54:40 -050070 if (rc < 0)
71 {
72 // Not found, continue to next metadata variable
73 logging::log<logging::level::INFO>("Failed to find metadata",
Adriana Kobylak7298dc22017-01-24 12:21:50 -060074 logging::entry("META_FIELD=%s", metaVarStr.c_str()));
Adriana Kobylakd311bc82016-10-16 09:54:40 -050075 continue;
76 }
77
78 // Metatdata variable found, write to file
Adriana Kobylak4ea7f312017-01-10 12:52:34 -060079 additionalData.push_back(std::string(data));
Adriana Kobylakd311bc82016-10-16 09:54:40 -050080 }
Adriana Kobylakd311bc82016-10-16 09:54:40 -050081
Adriana Kobylak1f36a882017-02-16 08:36:55 -060082 // TODO Remove once host event error header file is auto-generated.
83 // Tracking with issue openbmc/phosphor-logging#4
84 for (auto metaVarStrHostEvent : metalistHostEvent)
85 {
86 rc = sd_journal_get_data(j, metaVarStrHostEvent.c_str(),
87 (const void **)&data, &length);
88 if (rc < 0)
89 {
90 // Not found, continue to next metadata variable
91 logging::log<logging::level::INFO>("Failed to find metadata",
92 logging::entry("META_FIELD=%s",
93 metaVarStrHostEvent.c_str()));
94 continue;
95 }
96
97 // Metatdata variable found, write to file
98 additionalData.push_back(std::string(data));
Adriana Kobylak1f36a882017-02-16 08:36:55 -060099 }
100
Adriana Kobylakd311bc82016-10-16 09:54:40 -0500101 // TODO Break only once all metadata fields have been found. Implement
102 // once this function reads the metadata fields from the header file.
103 break;
104 }
105 sd_journal_close(j);
106
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600107 // Create error Entry dbus object
108 entryId++;
Adriana Kobylakc5f0bbd2017-01-22 14:56:04 -0600109 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
110 std::chrono::system_clock::now().time_since_epoch()).count();
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600111 auto objPath = std::string(OBJ_ENTRY) + '/' +
Adriana Kobylakc5f0bbd2017-01-22 14:56:04 -0600112 std::to_string(entryId);
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600113 entries.insert(std::make_pair(entryId, std::make_unique<Entry>(
114 busLog,
115 objPath,
116 entryId,
Adriana Kobylakc5f0bbd2017-01-22 14:56:04 -0600117 ms, // Milliseconds since 1970
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600118 (Entry::Level)g_errLevelMap[errMsg],
119 std::move(errMsg),
120 std::move(additionalData))));
Adriana Kobylak8f7941e2016-11-14 14:46:23 -0600121 return;
Adriana Kobylak1db1bd32016-10-10 11:39:20 -0500122}
123
Adriana Kobylak8f7941e2016-11-14 14:46:23 -0600124} // namespace logging
125} // namepsace phosphor