Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register a custom audit log item builder #12268

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion ydb/core/audit/audit_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <util/generic/string.h>
#include <util/generic/vector.h>

#include <ydb/core/base/events.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary here

#include <ydb/library/actors/core/actor.h>
#include <ydb/library/actors/core/executor_thread.h>

Expand Down Expand Up @@ -37,8 +38,10 @@ namespace NActors {

namespace NKikimr::NAudit {

using TAuditLogParts = TVector<std::pair<TString, TString>>;

extern std::atomic<bool> AUDIT_LOG_ENABLED;

void SendAuditLog(const NActors::TActorSystem* sys, TVector<std::pair<TString, TString>>&& parts);
void SendAuditLog(const NActors::TActorSystem* sys, TAuditLogParts&& parts);

} // namespace NKikimr::NAudit
67 changes: 35 additions & 32 deletions ydb/core/audit/audit_log_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
#include <ydb/library/actors/core/hfunc.h>
#include <ydb/library/services/services.pb.h>

#include <ydb/core/base/events.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary here


#include "audit_log_item_builder.h"
#include "audit_log_service.h"
#include "audit_log.h"

Expand Down Expand Up @@ -55,9 +54,9 @@ struct TEvAuditLog {

struct TEvWriteAuditLog : public NActors::TEventLocal<TEvWriteAuditLog, EvWriteAuditLog> {
TInstant Time;
TVector<std::pair<TString, TString>> Parts;
TAuditLogParts Parts;

TEvWriteAuditLog(TInstant time, TVector<std::pair<TString, TString>>&& parts)
TEvWriteAuditLog(TInstant time, TAuditLogParts&& parts)
: Time(time)
, Parts(std::move(parts))
{}
Expand All @@ -78,32 +77,30 @@ void WriteLog(const TString& log, const TVector<THolder<TLogBackend>>& logBacken
}
}

TString GetJsonLog(const TEvAuditLog::TEvWriteAuditLog::TPtr& ev) {
const auto* msg = ev->Get();
TString GetJsonLog(TInstant time, const TAuditLogParts& parts) {
TStringStream ss;
ss << msg->Time << ": ";
ss << time << ": ";
NJson::TJsonMap m;
for (auto& [k, v] : msg->Parts) {
for (auto& [k, v] : parts) {
m[k] = v;
}
NJson::WriteJson(&ss, &m, false, false);
ss << Endl;
return ss.Str();
}

TString GetJsonLogCompatibleLog(const TEvAuditLog::TEvWriteAuditLog::TPtr& ev) {
const auto* msg = ev->Get();
TString GetJsonLogCompatibleLog(TInstant time, const TAuditLogParts& parts) {
TStringStream ss;
NJsonWriter::TBuf json(NJsonWriter::HEM_DONT_ESCAPE_HTML, &ss);
{
auto obj = json.BeginObject();
obj
.WriteKey("@timestamp")
.WriteString(msg->Time.ToString().data())
.WriteString(time.ToString().data())
.WriteKey("@log_type")
.WriteString("audit");

for (auto& [k, v] : msg->Parts) {
for (auto& [k, v] : parts) {
obj.WriteKey(k).WriteString(v);
}
json.EndObject();
Expand All @@ -112,19 +109,33 @@ TString GetJsonLogCompatibleLog(const TEvAuditLog::TEvWriteAuditLog::TPtr& ev) {
return ss.Str();
}

TString GetTxtLog(const TEvAuditLog::TEvWriteAuditLog::TPtr& ev) {
const auto* msg = ev->Get();
TString GetTxtLog(TInstant time, const TAuditLogParts& parts) {
TStringStream ss;
ss << msg->Time << ": ";
for (auto it = msg->Parts.begin(); it != msg->Parts.end(); it++) {
if (it != msg->Parts.begin())
ss << time << ": ";
for (auto it = parts.begin(); it != parts.end(); it++) {
if (it != parts.begin())
ss << ", ";
ss << it->first << "=" << it->second;
}
ss << Endl;
return ss.Str();
}

// Array of functions for converting TEvAuditLog::TEvWriteAuditLog events to a string.
// Indexing in the array occurs by the value of the NKikimrConfig::TAuditConfig::EFormat enumeration.
// The size of AuditLogItemBuilders must be equal to the maximum value of the NKikimrConfig::TAuditConfig::EFormat enumeration.
static std::vector<TAuditLogItemBuilder> AuditLogItemBuilders = { GetJsonLog, GetTxtLog, GetJsonLogCompatibleLog, nullptr };

// numbering enumeration starts from one
static constexpr size_t DefaultAuditLogItemBuilder = static_cast<size_t>(NKikimrConfig::TAuditConfig::JSON) - 1;

void RegisterAuditLogItemBuilder(NKikimrConfig::TAuditConfig::EFormat format, TAuditLogItemBuilder builder) {
size_t index = static_cast<size_t>(format);
if (index < AuditLogItemBuilders.size()) {
AuditLogItemBuilders[index] = builder;
}
}

class TAuditLogActor final : public TActor<TAuditLogActor> {
private:
const TAuditLogBackends LogBackends;
Expand Down Expand Up @@ -160,20 +171,12 @@ class TAuditLogActor final : public TActor<TAuditLogActor> {
Y_UNUSED(ctx);

for (auto& logBackends : LogBackends) {
switch (logBackends.first) {
case NKikimrConfig::TAuditConfig::JSON:
WriteLog(GetJsonLog(ev), logBackends.second);
break;
case NKikimrConfig::TAuditConfig::TXT:
WriteLog(GetTxtLog(ev), logBackends.second);
break;
case NKikimrConfig::TAuditConfig::JSON_LOG_COMPATIBLE:
WriteLog(GetJsonLogCompatibleLog(ev), logBackends.second);
break;
default:
WriteLog(GetJsonLog(ev), logBackends.second);
break;
}
const auto builderIndex = static_cast<size_t>(logBackends.first) - 1;
const auto builder = builderIndex < AuditLogItemBuilders.size()
? AuditLogItemBuilders[builderIndex] : AuditLogItemBuilders[DefaultAuditLogItemBuilder];
const auto msg = ev->Get();
const auto auditLogItem = builder(msg->Time, msg->Parts);
WriteLog(auditLogItem, logBackends.second);
}
}

Expand All @@ -190,7 +193,7 @@ class TAuditLogActor final : public TActor<TAuditLogActor> {

std::atomic<bool> AUDIT_LOG_ENABLED = false;

void SendAuditLog(const NActors::TActorSystem* sys, TVector<std::pair<TString, TString>>&& parts)
void SendAuditLog(const NActors::TActorSystem* sys, TAuditLogParts&& parts)
{
auto request = MakeHolder<TEvAuditLog::TEvWriteAuditLog>(Now(), std::move(parts));
sys->Send(MakeAuditServiceID(), request.Release());
Expand Down
14 changes: 14 additions & 0 deletions ydb/core/audit/audit_log_item_builder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <ydb/core/audit/audit_log.h>
#include <ydb/core/protos/config.pb.h>


namespace NKikimr::NAudit {

using TAuditLogItemBuilder = TString(*)(TInstant, const TAuditLogParts&);

// Registration of a function for converting audit events to a string in a specified format
void RegisterAuditLogItemBuilder(NKikimrConfig::TAuditConfig::EFormat format, TAuditLogItemBuilder builder);

}
1 change: 1 addition & 0 deletions ydb/core/audit/ya.make
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
LIBRARY()

SRCS(
audit_log_item_builder.h
audit_log.h
audit_log_service.h
audit_log_impl.cpp
Expand Down
1 change: 1 addition & 0 deletions ydb/core/protos/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,7 @@ message TAuditConfig {
JSON = 1; // Outputs audit log in format: "<time>: {"k1": "v1", "k2": "v2", ...}" where <time> is ISO 8601 format time string, k1, k2, ..., kn - fields of audit log message and v1, v2, ..., vn are their values
TXT = 2; // Outputs audit log in format: "<time>: k1=v1, k2=v2, ..." where <time> is ISO 8601 format time string, k1, k2, ..., kn - fields of audit log message and v1, v2, ..., vn are their values
JSON_LOG_COMPATIBLE = 3; // Outputs audit log in format: "{"@timestamp": "<ISO 8601 time>", "@log_type": "audit", "k1": "v1", "k2": "v2", ...}" where @timestamp is ISO 8601 format time string, k1, k2, ..., kn - fields of audit log message and v1, v2, ..., vn are their values // Suitable for output both debug log and audit log to the same destination (stderr)
G_59548_2022 = 4; // Reserved
}

message TStderrBackend {
Expand Down
Loading