Repo-Init
 
Loading...
Searching...
No Matches
Sentry.cpp
Go to the documentation of this file.
1#include "logging/Sentry.hpp"
2
3#include "Version.h"
5
6#include <array>
7
8#include <arpa/inet.h>
9#include <ifaddrs.h>
10#include <net/if.h>
11#include <netpacket/packet.h>
12#include <unistd.h>
13
14#include <sentry.h>
15#include <spdlog/spdlog.h>
16
17// MAC address length for character string
18constexpr int MAC_LEN = 18;
19
20namespace spdlog::sinks
21{
22 template <typename Mutex> sentry_api_sink<Mutex>::sentry_api_sink(const std::string &sentryAddress)
23 {
24 if (sentryAddress.empty())
25 {
26 return;
27 }
28 _sentryAvailable = true;
29
30 // Set options
31 sentry_options_t *sentryOptions = sentry_options_new();
32 sentry_options_set_release(sentryOptions, PROJECT_FULL_REVISION);
33 sentry_options_set_dsn(sentryOptions, sentryAddress.c_str());
34
35 // Init
36 sentry_init(sentryOptions);
37
38 // Tags
39 sentry_set_tag("compiler.name", COMPILER_NAME);
40 sentry_set_tag("compiler.version", COMPILER_VERSION);
41 sentry_set_tag("build", BUILD_TYPE);
42
43 // Context: Version
44 std::string versionBuffer;
45 const sentry_value_t versionContext = sentry_value_new_object();
46 versionBuffer = "v" + std::string(PROJECT_FULL_REVISION);
47 sentry_value_set_by_key(versionContext, PROJECT_NAME, sentry_value_new_string(versionBuffer.c_str()));
48 versionBuffer = std::string(PROJECT_BUILD_DATE) + " " + PROJECT_BUILD_TIME;
49 sentry_value_set_by_key(versionContext, "Release Date", sentry_value_new_string(versionBuffer.c_str()));
50 /* ################################################################################### */
51 /* ############################# MAKE MODIFICATIONS HERE ############################# */
52 /* ################################################################################### */
53
54 /* ################################################################################### */
55 /* ################################ END MODIFICATIONS ################################ */
56 /* ################################################################################### */
57
58 sentry_set_context("Version", versionContext);
59
60 // Context: Host
61 std::array<char, BUFSIZ> hostBuffer{};
62 gethostname(hostBuffer.data(), BUFSIZ);
63 const sentry_value_t hostContext = sentry_value_new_object();
64 sentry_value_set_by_key(hostContext, "Hostname", sentry_value_new_string(hostBuffer.data()));
65
66 // Parse CPU information
67 const std::string cpuInfoPath = "/proc/cpuinfo";
68 std::string word;
69
70 findFromFile(cpuInfoPath, "^siblings", word);
71 sentry_value_set_by_key(hostContext, "Thread count", sentry_value_new_string(word.c_str()));
72 findFromFile(cpuInfoPath, "^(cpu cores)", word);
73 sentry_value_set_by_key(hostContext, "Core count", sentry_value_new_string(word.c_str()));
74 findFromFile(cpuInfoPath, "^(model name)", word);
75 sentry_value_set_by_key(hostContext, "Model", sentry_value_new_string(word.c_str()));
76 findFromFile(cpuInfoPath, "^vendor_id", word);
77 sentry_value_set_by_key(hostContext, "Vendor ID", sentry_value_new_string(word.c_str()));
78
79 sentry_set_context("Host", hostContext);
80
81 // Context: Network
82 const sentry_value_t networkContext = sentry_value_new_object();
83
84 if (ifaddrs *ifaddr = nullptr; getifaddrs(&ifaddr) != -1)
85 {
86 // Iterate interfaces
87 for (ifaddrs *ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
88 {
89 if (ifa->ifa_addr == nullptr)
90 {
91 continue;
92 }
93
94 switch (ifa->ifa_addr->sa_family)
95 {
96 case AF_INET:
97 if (((ifa->ifa_flags & IFF_PROMISC) != 0) || ((ifa->ifa_flags & IFF_UP) != 0))
98 {
99 std::array<char, INET_ADDRSTRLEN> host{};
100 inet_ntop(AF_INET, &(reinterpret_cast<sockaddr_in *>(ifa->ifa_addr))->sin_addr, host.data(),
101 INET_ADDRSTRLEN);
102 sentry_value_set_by_key(networkContext, (std::string(ifa->ifa_name) + ".ipv4").c_str(),
103 sentry_value_new_string(host.data()));
104 }
105 break;
106 case AF_INET6:
107 if (((ifa->ifa_flags & IFF_PROMISC) != 0) || ((ifa->ifa_flags & IFF_UP) != 0))
108 {
109 std::array<char, INET6_ADDRSTRLEN> host{};
110 inet_ntop(AF_INET6, &(reinterpret_cast<sockaddr_in6 *>(ifa->ifa_addr))->sin6_addr, host.data(),
111 INET6_ADDRSTRLEN);
112 sentry_value_set_by_key(networkContext, (std::string(ifa->ifa_name) + ".ipv6").c_str(),
113 sentry_value_new_string(host.data()));
114 }
115 break;
116 case AF_PACKET:
117 if (((ifa->ifa_flags & IFF_PROMISC) != 0) || ((ifa->ifa_flags & IFF_UP) != 0))
118 {
119 std::array<char, MAC_LEN> host{};
120 const auto *sock = reinterpret_cast<sockaddr_ll *>(ifa->ifa_addr);
121 if (snprintf(host.data(), MAC_LEN, "%02x:%02x:%02x:%02x:%02x:%02x", sock->sll_addr[0],
122 sock->sll_addr[1], sock->sll_addr[2], sock->sll_addr[3], sock->sll_addr[4],
123 sock->sll_addr[5]) > 0)
124 {
125 sentry_value_set_by_key(networkContext, (std::string(ifa->ifa_name) + ".mac").c_str(),
126 sentry_value_new_string(host.data()));
127 }
128 }
129 break;
130 default:
131 break;
132 }
133 }
134 freeifaddrs(ifaddr);
135 }
136 sentry_set_context("Network", networkContext);
137 }
138
139 template <typename Mutex> sentry_api_sink<Mutex>::~sentry_api_sink() { sentry_close(); }
140
141 template <typename Mutex> void sentry_api_sink<Mutex>::sink_it_(const details::log_msg &msg)
142 {
143 if (!_sentryAvailable)
144 {
145 return;
146 }
147 switch (msg.level)
148 {
149 case spdlog::level::warn:
150 sentry_capture_event(sentry_value_new_message_event(
151 SENTRY_LEVEL_WARNING, "main", std::string(msg.payload.data(), msg.payload.size()).c_str()));
152 break;
153 case spdlog::level::err:
154 sentry_capture_event(sentry_value_new_message_event(
155 SENTRY_LEVEL_ERROR, "main", std::string(msg.payload.data(), msg.payload.size()).c_str()));
156 break;
157 case spdlog::level::critical:
158 sentry_capture_event(sentry_value_new_message_event(
159 SENTRY_LEVEL_FATAL, "main", std::string(msg.payload.data(), msg.payload.size()).c_str()));
160 break;
161 case spdlog::level::trace:
162 case spdlog::level::debug:
163 case spdlog::level::info:
164 case spdlog::level::off:
165 // For lower levels, do nothing for now. But you can easily handle them here.
166 default:
167 break;
168 }
169 }
170
171 template <typename Mutex> void sentry_api_sink<Mutex>::flush_() {}
172
173 template class sentry_api_sink<std::mutex>;
175} // namespace spdlog::sinks
std::vector< std::string > findFromFile(const std::string &filePath, const std::string &pattern, std::string &lastWord)
constexpr int MAC_LEN
Definition Sentry.cpp:18
sentry_api_sink(const std::string &sentryAddress)
Definition Sentry.cpp:22
void sink_it_(const details::log_msg &msg) override
Definition Sentry.cpp:141