129 lines
3.3 KiB
C++
129 lines
3.3 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)
|
|
{
|
|
this->winCurrentSink_ = RegisterEventSourceW(NULL, Locale::ConvertFromUTF8(value).c_str());
|
|
}
|
|
|
|
EventLogSink::~EventLogSink()
|
|
{
|
|
DeregisterEventSource(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();
|
|
ReportEventW(this->winCurrentSink_, AuGet<0>(sortedMessages), 0, kMagicEventNumber, NULL, 1, 0, (CONST WCHAR **)&handle, NULL);
|
|
}
|
|
|
|
this->winCompleteArrayBuffer_.clear();
|
|
}
|
|
|
|
IBasicSink *NewOSNamedEventDirectorySinkNew(const AuString &name)
|
|
{
|
|
try
|
|
{
|
|
return _new EventLogSink(name);
|
|
}
|
|
catch (...)
|
|
{
|
|
return {};
|
|
}
|
|
}
|
|
|
|
void NewOSNamedEventDirectorySinkRelease(IBasicSink *sink)
|
|
{
|
|
AuSafeDelete< EventLogSink *>(sink);
|
|
}
|
|
} |