AuroraRuntime/Source/Logging/Sinks/EventLog.Win32.cpp

141 lines
3.5 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EventLog.Win32.cpp
Date: 2022-2-6
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "EventLog.Win32.hpp"
namespace Aurora::Logging::Sinks
{
static const auto kMagicEventNumber = 1000;
EventLogSink::EventLogSink(const AuString &value)
{
SysAssert(pRegisterEventSourceW);
this->winCurrentSink_ = pRegisterEventSourceW(NULL, Locale::ConvertFromUTF8(value).c_str());
}
EventLogSink::~EventLogSink()
{
SysAssert(pDeregisterEventSource);
pDeregisterEventSource(winCurrentSink_);
}
bool EventLogSink::OnMessageNonblocking(AuUInt8 level, const ConsoleMessage &msg)
{
if (this->winCurrentSink_ == INVALID_HANDLE_VALUE)
{
return false;
}
return true;
}
void EventLogSink::OnMessageBlocking(AuUInt8 level, const ConsoleMessage &msg)
{
if (this->winCurrentSink_ == INVALID_HANDLE_VALUE)
{
return;
}
AU_LOCK_GUARD(this->spinLock_);
WORD type {};
switch (level)
{
case (AuUInt8)ELogLevel::eInfo:
type = EVENTLOG_SUCCESS;
break;
case (AuUInt8)ELogLevel::eError:
type = EVENTLOG_ERROR_TYPE;
break;
case (AuUInt8)ELogLevel::eDebug:
case (AuUInt8)ELogLevel::eVerbose:
type = EVENTLOG_INFORMATION_TYPE;
break;
case (AuUInt8)ELogLevel::eWarn:
type = EVENTLOG_WARNING_TYPE;
break;
default:
type = EVENTLOG_INFORMATION_TYPE;
}
if (this->winCurrentType_ != type)
{
FlushStrings();
this->winCurrentType_ = type;
}
auto a = Locale::ConvertFromUTF8(msg.ToPersistentString());
if (this->winArrayBuffer_.size() + a.size() + 2 >= 32 * 1000)
{
FlushStrings();
}
this->winArrayBuffer_.insert(this->winArrayBuffer_.end(), a.begin(), a.end());
this->winArrayBuffer_.insert(this->winArrayBuffer_.end(), L"\r\n", L"\r\n" + 2);
}
void EventLogSink::FlushStrings()
{
if (this->winArrayBuffer_.empty())
{
return;
}
this->winCompleteArrayBuffer_.push_back(AuMakeTuple(this->winCurrentType_, AuMove(this->winArrayBuffer_)));
this->winArrayBuffer_.clear();
this->winArrayBuffer_.reserve(15 * 1024);
}
void EventLogSink::OnFlush()
{
if (this->winCurrentSink_ == INVALID_HANDLE_VALUE)
{
return;
}
AU_LOCK_GUARD(this->spinLock_);
FlushStrings();
for (auto &sortedMessages : this->winCompleteArrayBuffer_)
{
auto &strs = AuGet<1>(sortedMessages);
auto handle = strs.data();
if (!pReportEventW)
{
return;
}
pReportEventW(this->winCurrentSink_, AuGet<0>(sortedMessages), 0, kMagicEventNumber, NULL, 1, 0, (CONST WCHAR **)&handle, NULL);
}
this->winCompleteArrayBuffer_.clear();
}
IBasicSink *NewOSNamedEventDirectorySinkNew(const AuString &name)
{
if (!pReportEventW)
{
return {};
}
try
{
return _new EventLogSink(name);
}
catch (...)
{
return {};
}
}
void NewOSNamedEventDirectorySinkRelease(IBasicSink *sink)
{
AuSafeDelete< EventLogSink *>(sink);
}
}