|
2 | 2 |
|
3 | 3 | #include <binlog/Entries.hpp> |
4 | 4 | #include <nlohmann/json.hpp> |
| 5 | +#include "absl/strings/str_join.h" |
| 6 | +#include "absl/strings/str_cat.h" |
| 7 | +#include "absl/strings/str_split.h" |
5 | 8 |
|
6 | 9 | namespace codeql { |
7 | | -SwiftDiagnosticsSource::SwiftDiagnosticsSource(std::string_view internalId, |
8 | | - std::string&& name, |
9 | | - std::vector<std::string>&& helpLinks, |
10 | | - std::string&& action) |
11 | | - : name{std::move(name)}, helpLinks{std::move(helpLinks)}, action{std::move(action)} { |
12 | | - id = extractorName; |
13 | | - id += '/'; |
14 | | - id += programName; |
15 | | - id += '/'; |
16 | | - std::transform(internalId.begin(), internalId.end(), std::back_inserter(id), |
17 | | - [](char c) { return c == '_' ? '-' : c; }); |
18 | | -} |
19 | | - |
20 | | -void SwiftDiagnosticsSource::create(std::string_view id, |
21 | | - std::string name, |
22 | | - std::vector<std::string> helpLinks, |
23 | | - std::string action) { |
24 | | - auto [it, inserted] = map().emplace( |
25 | | - id, SwiftDiagnosticsSource{id, std::move(name), std::move(helpLinks), std::move(action)}); |
26 | | - assert(inserted); |
27 | | -} |
28 | | - |
29 | 10 | void SwiftDiagnosticsSource::emit(std::ostream& out, |
30 | 11 | std::string_view timestamp, |
31 | 12 | std::string_view message) const { |
32 | | - nlohmann::json entry; |
33 | | - auto& source = entry["source"]; |
34 | | - source["id"] = id; |
35 | | - source["name"] = name; |
36 | | - source["extractorName"] = extractorName; |
37 | | - |
38 | | - auto& visibility = entry["visibility"]; |
39 | | - visibility["statusPage"] = true; |
40 | | - visibility["cliSummaryTable"] = true; |
41 | | - visibility["telemetry"] = true; |
42 | | - |
43 | | - entry["severity"] = "error"; |
44 | | - entry["helpLinks"] = helpLinks; |
45 | | - std::string plaintextMessage{message}; |
46 | | - plaintextMessage += ".\n\n"; |
47 | | - plaintextMessage += action; |
48 | | - plaintextMessage += '.'; |
49 | | - entry["plaintextMessage"] = plaintextMessage; |
50 | | - |
51 | | - entry["timestamp"] = timestamp; |
52 | | - |
| 13 | + nlohmann::json entry = { |
| 14 | + {"source", |
| 15 | + { |
| 16 | + {"id", sourceId()}, |
| 17 | + {"name", name}, |
| 18 | + {"extractorName", extractorName}, |
| 19 | + }}, |
| 20 | + {"visibility", |
| 21 | + { |
| 22 | + {"statusPage", true}, |
| 23 | + {"cliSummaryTable", true}, |
| 24 | + {"telemetry", true}, |
| 25 | + }}, |
| 26 | + {"severity", "error"}, |
| 27 | + {"helpLinks", std::vector<std::string_view>(absl::StrSplit(helpLinks, ' '))}, |
| 28 | + {"plaintextMessage", absl::StrCat(message, ".\n\n", action, ".")}, |
| 29 | + {"timestamp", timestamp}, |
| 30 | + }; |
53 | 31 | out << entry << '\n'; |
54 | 32 | } |
55 | 33 |
|
| 34 | +std::string SwiftDiagnosticsSource::sourceId() const { |
| 35 | + auto ret = absl::StrJoin({extractorName, programName, id}, "/"); |
| 36 | + std::replace(ret.begin(), ret.end(), '_', '-'); |
| 37 | + return ret; |
| 38 | +} |
| 39 | + |
56 | 40 | void SwiftDiagnosticsDumper::write(const char* buffer, std::size_t bufferSize) { |
57 | 41 | binlog::Range range{buffer, bufferSize}; |
58 | 42 | binlog::RangeEntryStream input{range}; |
59 | 43 | while (auto event = events.nextEvent(input)) { |
60 | 44 | const auto& source = SwiftDiagnosticsSource::get(event->source->category); |
61 | 45 | std::ostringstream oss; |
62 | 46 | timestampedMessagePrinter.printEvent(oss, *event, events.writerProp(), events.clockSync()); |
| 47 | + // TODO(C++20) use oss.view() directly |
63 | 48 | auto data = oss.str(); |
64 | 49 | std::string_view view = data; |
65 | | - auto sep = view.find(' '); |
66 | | - assert(sep != std::string::npos); |
67 | | - auto timestamp = view.substr(0, sep); |
68 | | - auto message = view.substr(sep + 1); |
| 50 | + using ViewPair = std::pair<std::string_view, std::string_view>; |
| 51 | + auto [timestamp, message] = ViewPair(absl::StrSplit(view, absl::MaxSplits(' ', 1))); |
69 | 52 | source.emit(output, timestamp, message); |
70 | 53 | } |
71 | 54 | } |
|
0 commit comments