Repository navigation
Expand file tree
/
Copy pathevent.cpp
More file actions
112 lines (107 loc) · 4.26 KB
/
Copy pathevent.cpp
File metadata and controls
112 lines (107 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <teaql/runtime/detail/governance_scope.hpp>
#include <teaql/runtime/detail/commit_audit.hpp>
#include <teaql/runtime/event.hpp>
#include <teaql/runtime/log_manager.hpp>
#include <teaql/runtime/telemetry.hpp>
#include <chrono>
namespace teaql {
Result<std::monostate, RuntimeError> UserContext::send_event(const RawAuditEvent& input) const {
ensure_open();
auto r = memory_resource();
Arena::Quiescence active;
active.attach(detail::resource_arena(r), nullptr, [](void*) noexcept {
std::terminate();
});
using R = Result<std::monostate, RuntimeError>;
auto event = detail::clone_in(r, input);
event.mutation_governance = detail::current_mutation_governance(*this);
if (detail::is_generated_schema_bootstrap(*this) &&
(event.kind == RawAuditEventKind::Created || event.kind == RawAuditEventKind::Updated)) {
const Value* version = nullptr;
if (event.new_values) {
auto found = event.new_values->find(std::string_view("version"));
if (found != event.new_values->end()) {
version = &found->second;
}
}
if (!version) {
auto found = event.values.find(std::string_view("version"));
if (found != event.values.end()) {
version = &found->second;
}
}
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
event.bootstrap_audit.emplace(std::allocator_arg,
Allocator(r),
"teaql-generated-bootstrap",
"runtime-bootstrap",
event.trace_chain.empty()
? std::string_view("generated runtime bootstrap")
: std::string_view(event.trace_chain.back().comment),
version ? version->try_i64() : std::nullopt,
millis < 0 ? 0 : static_cast<std::uint64_t>(millis));
}
if (detail::enqueue_audit(*this, event)) {
return R::ok(r, {});
}
return deliver_audit_event(event);
}
Result<std::monostate, RuntimeError>
UserContext::deliver_audit_event(const RawAuditEvent& event) const {
ensure_open();
auto r = memory_resource();
Arena::Quiescence active;
active.attach(detail::resource_arena(r), nullptr, [](void*) noexcept {
std::terminate();
});
using R = Result<std::monostate, RuntimeError>;
String name(event.entity, r);
name += ".event";
RuntimeOperation operation(std::allocator_arg, Allocator(r), "audit", name);
operation.attribute("teaql.entity.type", std::string_view(event.entity));
auto& scope = start_runtime_operation(operation);
struct Close {
FailOpenRuntimeTelemetryScope& scope;
~Close() {
scope.close();
}
} close{scope};
auto send = [&]() -> R {
if (event_sink_) {
if (event_sink_borrow_) {
(void)event_sink_borrow_->get();
}
auto result = event_sink_->on_event(r, *this, event);
if (!result) {
return R::err(r, std::move(result).error());
}
}
if (custom_event_sink_) {
if (custom_event_sink_borrow_) {
(void)custom_event_sink_borrow_->get();
}
auto* descriptor = entity(event.entity);
auto safe = event.build_safe_event(
r,
descriptor ? std::span<const String>(descriptor->audit_mask_fields)
: std::span<const String>{},
descriptor ? descriptor->audit_value_max_len : std::nullopt);
auto result = custom_event_sink_->on_safe_event(r, *this, safe);
if (!result) {
return R::err(r, std::move(result).error());
}
}
global_.log_manager().write_audit_log(r, event);
return R::ok(r, {});
};
auto result = send();
if (result) {
scope.success(RuntimeAttributes(r));
} else {
scope.failure("audit_error");
}
return result;
}
}