blob: 991113825ab90ec36f66ae219ea78b9943d8823c [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);
Adriana Kobylak9aa7d782017-02-18 09:20:49 -060036 auto& metalist = g_errMetaMap[errMsg];
37 const auto& 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 Kobylak9aa7d782017-02-18 09:20:49 -060040 // TODO Remove once host event error header file is auto-generated.
41 // Also make metalist a const variable.
42 // Tracking with issue openbmc/phosphor-logging#4
43 for (auto& metaVarStrHostEvent : metalistHostEvent)
Adriana Kobylakd311bc82016-10-16 09:54:40 -050044 {
Adriana Kobylak9aa7d782017-02-18 09:20:49 -060045 metalist.push_back(metaVarStrHostEvent);
Adriana Kobylakd311bc82016-10-16 09:54:40 -050046 }
Adriana Kobylak9aa7d782017-02-18 09:20:49 -060047
48 // Search for each metadata variable in the journal.
49 for (auto& metaVarStr : metalist)
50 {
51 const char *metadata = nullptr;
52
53 // Read the journal from the end to get the most recent entry first.
54 // The result from the sd_journal_get_data() is of the form VARIABLE=value.
55 SD_JOURNAL_FOREACH_BACKWARDS(j)
56 {
57 const char *data = nullptr;
58 size_t length = 0;
59 metadata = nullptr;
60
61 // Search for the metadata variables in the current journal entry
62 rc = sd_journal_get_data(j, metaVarStr.c_str(),
63 (const void **)&metadata, &length);
64 if (rc < 0)
65 {
66 // Metadata value not found, continue to next journal entry.
67 continue;
68 }
69
70 // Look for the transaction id metadata variable
71 rc = sd_journal_get_data(j, transactionIdVar, (const void **)&data,
72 &length);
73 if (rc < 0)
74 {
75 // This journal entry does not have the transaction id,
76 // continue to next entry
77 continue;
78 }
79
80 std::string result(data);
81 if (result.find(transactionIdStr) == std::string::npos)
82 {
83 // Requested transaction id not found,
84 // continue to next journal entry.
85 continue;
86 }
87
88 // Metadata matching the transaction id found, save it
89 // and break out of the journal search loop
90 additionalData.push_back(std::string(metadata));
91 break;
92 }
93 if (!metadata)
94 {
95 // Metadata value not found in the journal.
96 logging::log<logging::level::INFO>("Failed to find metadata",
97 logging::entry("META_FIELD=%s", metaVarStr.c_str()));
98 continue;
99 }
100 }
101
Adriana Kobylakd311bc82016-10-16 09:54:40 -0500102 sd_journal_close(j);
103
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600104 // Create error Entry dbus object
105 entryId++;
Adriana Kobylakc5f0bbd2017-01-22 14:56:04 -0600106 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
107 std::chrono::system_clock::now().time_since_epoch()).count();
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600108 auto objPath = std::string(OBJ_ENTRY) + '/' +
Adriana Kobylakc5f0bbd2017-01-22 14:56:04 -0600109 std::to_string(entryId);
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600110 entries.insert(std::make_pair(entryId, std::make_unique<Entry>(
111 busLog,
112 objPath,
113 entryId,
Adriana Kobylakc5f0bbd2017-01-22 14:56:04 -0600114 ms, // Milliseconds since 1970
Adriana Kobylak4ea7f312017-01-10 12:52:34 -0600115 (Entry::Level)g_errLevelMap[errMsg],
116 std::move(errMsg),
117 std::move(additionalData))));
Adriana Kobylak8f7941e2016-11-14 14:46:23 -0600118 return;
Adriana Kobylak1db1bd32016-10-10 11:39:20 -0500119}
120
Adriana Kobylak8f7941e2016-11-14 14:46:23 -0600121} // namespace logging
122} // namepsace phosphor