Skip to content
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
44 changes: 44 additions & 0 deletions src/runtime_src/core/common/detail/linux/syslog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved.

// POSIX syslog implementation of syslog_dispatch.

#include "core/common/message.h"
Comment thread
rbramand-xilinx marked this conversation as resolved.

#include <map>
#include <syslog.h>

namespace xrt_core::message {

class syslog_dispatch : public message_dispatch
Comment thread
rbramand-xilinx marked this conversation as resolved.
{
public:
syslog_dispatch()
{ openlog("sdaccel", LOG_PID|LOG_CONS, LOG_USER); }

syslog_dispatch(const syslog_dispatch&) = delete;
syslog_dispatch& operator=(const syslog_dispatch&) = delete;
syslog_dispatch(syslog_dispatch&&) = delete;
syslog_dispatch& operator=(syslog_dispatch&&) = delete;

~syslog_dispatch() override
{ closelog(); }

void
send(severity_level l, const char* tag, const char* msg) override
{ syslog(m_severity_map[l], "%s", msg); }

private:
std::map<severity_level, int> m_severity_map = {
{ severity_level::emergency, LOG_EMERG },
{ severity_level::alert, LOG_ALERT },
{ severity_level::critical, LOG_CRIT },
{ severity_level::error, LOG_ERR },
{ severity_level::warning, LOG_WARNING },
{ severity_level::notice, LOG_NOTICE },
{ severity_level::info, LOG_INFO },
{ severity_level::debug, LOG_DEBUG }
};
};

} // xrt_core::message
12 changes: 12 additions & 0 deletions src/runtime_src/core/common/detail/syslog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved.
#ifndef core_common_detail_syslog_h
#define core_common_detail_syslog_h

#ifdef _WIN32
# include "core/common/detail/windows/syslog.h"
#else
# include "core/common/detail/linux/syslog.h"
#endif

#endif
93 changes: 93 additions & 0 deletions src/runtime_src/core/common/detail/windows/syslog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved.

// Windows Event Log implementation of syslog_dispatch.
// Routes XRT messages to the Application event log under source "AMD_XRT".
//
// Filter in Event Viewer:
// Windows Logs -> Application -> Source: AMD_XRT
// Filter via PowerShell:
// Get-EventLog -LogName Application -Source "AMD_XRT"
// Get-EventLog -LogName Application -Source "AMD_XRT" -EntryType Error
// Get-EventLog -LogName Application -Source "AMD_XRT" -EntryType Error,Warning
// Filter via cmd (Level: 2=Error, 3=Warning, 4=Information):
// wevtutil qe Application /q:"*[System[Provider[@Name='AMD_XRT']]]" /f:text
// wevtutil qe Application /q:"*[System[Provider[@Name='AMD_XRT'] and Level=2]]" /f:text
// wevtutil qe Application /q:"*[System[Provider[@Name='AMD_XRT'] and (Level=2 or Level=3)]]" /f:text

#include "core/common/message.h"

#include <array>
#include <iostream>
#include <string>
#include <windows.h>
Comment thread
rbramand-xilinx marked this conversation as resolved.

#pragma comment(lib, "Advapi32.lib") // for Windows Event Log APIs

namespace xrt_core::message {

class syslog_dispatch : public message_dispatch
Comment thread
rbramand-xilinx marked this conversation as resolved.
{
public:
syslog_dispatch()
{
// RegisterEventSourceA opens a handle to the Application event log and
// associates it with the source name "AMD_XRT". Registry registration of
// "AMD_XRT" as a known source is done at driver install time via the INF
// AddReg directive. This call does not require admin rights.
m_handle = RegisterEventSourceA(nullptr, "AMD_XRT");
// Do not throw on failure: this is constructed lazily on first
// xrt_core::message::send(), so a throw here would crash the application
// if the Windows Event Log service is unavailable.
if (!m_handle)
std::cerr << "XRT: Failed to open Windows Event Log source 'AMD_XRT' "
<< "(error " << GetLastError() << "). Logging disabled.\n";
}

syslog_dispatch(const syslog_dispatch&) = delete;
syslog_dispatch& operator=(const syslog_dispatch&) = delete;
syslog_dispatch(syslog_dispatch&&) = delete;
syslog_dispatch& operator=(syslog_dispatch&&) = delete;

~syslog_dispatch() override
Comment thread
rbramand-xilinx marked this conversation as resolved.
{
if (m_handle)
DeregisterEventSource(m_handle);
}

void
send(severity_level l, const char* tag, const char* msg) override
{
if (!m_handle)
return;

std::string full_msg = std::string("[") + tag + "] : " + msg;
std::array<LPCSTR, 1> strings = {full_msg.c_str()};
// Event ID 1 matches the pass-through entry in EventCreate.exe's message
// table (%1), so Event Viewer displays our text directly without a warning.
// Severity filtering uses wType (Level column), not event ID.
static constexpr DWORD event_id = 1;
ReportEventA(m_handle, to_event_type(l), 0, event_id,
nullptr, 1, 0, strings.data(), nullptr);
}

private:
HANDLE m_handle = nullptr;

// Maps XRT severity to Windows event type (controls icon in Event Viewer):
// EVENTLOG_ERROR_TYPE -> red X (emergency/alert/critical/error)
// EVENTLOG_WARNING_TYPE -> yellow triangle
// EVENTLOG_INFORMATION_TYPE -> blue i (notice/info/debug)
static WORD
to_event_type(severity_level l)
{
if (l == severity_level::warning)
return EVENTLOG_WARNING_TYPE;
if (l == severity_level::emergency || l == severity_level::alert ||
l == severity_level::critical || l == severity_level::error)
return EVENTLOG_ERROR_TYPE;
return EVENTLOG_INFORMATION_TYPE;
}
};

} // xrt_core::message
96 changes: 24 additions & 72 deletions src/runtime_src/core/common/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "config_reader.h"
#include "utils.h"

#include "detail/syslog.h" // for syslog_dispatch

#include "xrt/detail/version-git.h"

#include <algorithm>
Expand All @@ -19,14 +21,10 @@
#include <mutex>
#include <thread>
#ifdef __linux__
# include <syslog.h>
# include <linux/limits.h>
# include <sys/stat.h>
# include <sys/types.h>
#endif
#ifdef _WIN32
# include <winsock.h>
#endif

namespace {

Expand Down Expand Up @@ -54,17 +52,7 @@ get_exe_path()


using severity_level = xrt_core::message::severity_level;

//--
class message_dispatch
{
public:
message_dispatch() {}
virtual ~message_dispatch() {}
static message_dispatch* make_dispatcher(const std::string& choice);
public:
virtual void send(severity_level l, const char* tag, const char* msg) = 0;
};
using message_dispatch = xrt_core::message::message_dispatch;

//--
class null_dispatch : public message_dispatch
Expand All @@ -82,6 +70,7 @@ class console_dispatch : public message_dispatch
console_dispatch();
virtual ~console_dispatch() {}
virtual void send(severity_level l, const char* tag, const char* msg) override;

private:
std::map<severity_level, const char*> severityMap = {
{ severity_level::emergency, "EMERGENCY: "},
Expand All @@ -95,34 +84,6 @@ class console_dispatch : public message_dispatch
};
};

//--
#ifndef _WIN32
class syslog_dispatch : public message_dispatch
{
public:
syslog_dispatch()
{ openlog("sdaccel", LOG_PID|LOG_CONS, LOG_USER); }

virtual ~syslog_dispatch()
{ closelog(); }

virtual void send(severity_level l, const char* tag, const char* msg) override
{ syslog(severityMap[l], "%s", msg); }

private:
std::map<severity_level, int> severityMap = {
{ severity_level::emergency, LOG_EMERG},
{ severity_level::alert, LOG_ALERT},
{ severity_level::critical, LOG_CRIT},
{ severity_level::error, LOG_ERR},
{ severity_level::warning, LOG_WARNING},
{ severity_level::notice, LOG_NOTICE},
{ severity_level::info, LOG_INFO},
{ severity_level::debug, LOG_DEBUG}
};
};
#endif

//--
class file_dispatch : public message_dispatch
{
Expand All @@ -145,34 +106,6 @@ class file_dispatch : public message_dispatch
};
};

//-------
message_dispatch*
message_dispatch::
make_dispatcher(const std::string& choice)
{
if( (choice == "null") || (choice == ""))
return new null_dispatch;
else if(choice == "console")
return new console_dispatch;
else if(choice == "syslog") {
#ifndef _WIN32
return new syslog_dispatch;
#else
throw std::runtime_error("syslog not supported on windows");
#endif
}
else {
if(choice.front() == '"') {
std::string file = choice;
file.erase(0, 1);
file.erase(file.size()-1);
return new file_dispatch(file);
}
else
return new file_dispatch(choice);
}
}

//file ops
file_dispatch::
file_dispatch(const std::string &file)
Expand Down Expand Up @@ -233,6 +166,25 @@ send(severity_level l, const char* tag, const char* msg)

namespace xrt_core { namespace message {

std::unique_ptr<message_dispatch>
message_dispatch::
make_dispatcher(const std::string& choice)
{
if ((choice == "null") || (choice == ""))
return std::make_unique<null_dispatch>();
if (choice == "console")
return std::make_unique<console_dispatch>();
if (choice == "syslog")
return std::make_unique<syslog_dispatch>();

std::string file = choice;
if (file.front() == '"') {
file.erase(0, 1);
file.erase(file.size()-1);
}
return std::make_unique<file_dispatch>(file);
}

void
send(severity_level l, const char* tag, const char* msg)
{
Expand All @@ -241,7 +193,7 @@ send(severity_level l, const char* tag, const char* msg)
int lev = static_cast<int>(l);

if(ver >= lev) {
static message_dispatch* dispatcher = message_dispatch::make_dispatcher(logger);
static auto dispatcher = message_dispatch::make_dispatcher(logger);
dispatcher->send(l, tag, msg);
}
}
Expand Down
36 changes: 21 additions & 15 deletions src/runtime_src/core/common/message.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
/**
* Copyright (C) 2016-2021 Xilinx, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may
* not use this file except in compliance with the License. A copy of the
* License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2016-2022 Xilinx, Inc. All rights reserved.
// Copyright (C) 2022-2026 Advanced Micro Devices, Inc. All rights reserved.

#ifndef xrtcore_message_h_
#define xrtcore_message_h_
#include "core/common/config.h"
#include "core/common/config_reader.h"
#include "core/include/xrt.h"
#include "core/include/xrt/experimental/xrt_message.h"
#include <memory>
#include <string>
#include <cstdio>
#include <vector>
Expand All @@ -28,6 +17,23 @@ namespace xrt_core { namespace message {

using severity_level = xrt::message::level;

class message_dispatch
Comment thread
rbramand-xilinx marked this conversation as resolved.
{
public:
message_dispatch() = default;
message_dispatch(const message_dispatch&) = delete;
message_dispatch& operator=(const message_dispatch&) = delete;
message_dispatch(message_dispatch&&) = delete;
message_dispatch& operator=(message_dispatch&&) = delete;
virtual ~message_dispatch() = default;

static std::unique_ptr<message_dispatch>
make_dispatcher(const std::string& choice);

virtual void
send(severity_level l, const char* tag, const char* msg) = 0;
};

XRT_CORE_COMMON_EXPORT
void
send(severity_level l, const char* tag, const char* msg);
Expand Down
14 changes: 11 additions & 3 deletions src/runtime_src/core/include/xrt/experimental/xrt_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,17 @@
*
* @details
* XRT internally uses a message system that supports dispatching of
* messages to null, console, file, or syslog under different verbosity
* levels. The sink and verbosity level is controlled statically
* through ``xrt.ini`` or at run-time using ``xrt::ini``.
* messages to different sinks under configurable verbosity levels.
* The sink and verbosity level is controlled statically through
* ``xrt.ini`` or at run-time using ``xrt::ini``.
*
* Supported sinks (``Runtime.runtime_log`` in xrt.ini):
* - ``null`` : discard all messages
* - ``console`` : writes to console (default)
* - ``syslog`` : route to OS-level centralized log (all platforms):
* Linux uses POSIX syslog; Windows uses the Windows
* Application Event Log under source "AMD_XRT"
* - ``<path>`` : write to a file at the given path (all platforms)
*
* The APIs in this file allow host application to use the same
* message dispatch mechanism as XRT is configured to use.
Expand Down
Loading
Loading