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
11 changes: 0 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,6 @@ else()
endif()
add_definitions(-DLOADER_VERSION_SHA="${VERSION_SHA}")

if(SYSTEM_SPDLOG)
find_package(spdlog CONFIG)
if(spdlog_FOUND)
message(STATUS "System spdlog found.")
else()
message(FATAL_ERROR "SYSTEM_SPDLOG specified but spdlog wasn't found.")
endif()
else()
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/third_party/spdlog_headers")
endif()

include(FetchContent)

if(BUILD_L0_LOADER_TESTS)
Expand Down
67 changes: 46 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,39 +46,62 @@ When the `-DBUILD_STATIC=1` is executed, the dynamic loader and layers are not b
Testing with the static loader requires a build of the dynamic loader or an installation of the dynamic loader to exist in the library path.

# Debug Trace

> **Deprecated:** `ZE_ENABLE_LOADER_DEBUG_TRACE` is deprecated and will be removed in a future release.
> Use `ZEL_LOADER_LOG_CONSOLE=1` with `ZEL_LOADER_LOGGING_LEVEL=trace` instead, which provides
> the same or enhanced information with structured timestamps, thread IDs, and log levels via the logging system.

The Level Zero Loader has the ability to print warnings and errors which occur within the internals of the Level Zero Loader itself.

To enable this debug tracing feature, set the environment variable `ZE_ENABLE_LOADER_DEBUG_TRACE=1`.

This will enforce the Loader to print all errors whether fatal or non-fatal to stderr with the PREFIX `ZE_LOADER_DEBUG_TRACE:`.


# Logging to File - PREVIEW
The Level Zero Loader uses spdlog logging and can be controlled via environment variables:
# Logging to File or Console
The Level Zero Loader provides built-in logging controlled via environment variables:

`ZEL_ENABLE_LOADER_LOGGING=1`
| Environment Variable | Default | Description |
|---|---|---|
| `ZEL_ENABLE_LOADER_LOGGING` | `0` | Set to `1` to enable file logging |
| `ZEL_LOADER_LOG_CONSOLE` | `0` | Set to `1` to enable console (stderr) logging, overrides file logging |
| `ZEL_LOADER_LOGGING_LEVEL` | `warn` | Log level: `trace`, `debug`, `info`, `warn`, `error`, `critical`, `off` |
| `ZEL_LOADER_LOG_DIR` | `~/.oneapi_logs` | Directory to write the log file into |
| `ZEL_LOADER_LOG_FILE` | `ze_loader.log` | Log filename |
| `ZEL_LOADER_LOG_PATTERN` | see below | Custom log format pattern |

## Output destination

`ZEL_LOADER_LOG_DIR='/directory/path'`
The two flags control output as follows:

`ZEL_LOADER_LOGGING_LEVEL=debug`
| `ZEL_ENABLE_LOADER_LOGGING` | `ZEL_LOADER_LOG_CONSOLE` | Output |
|---|---|---|
| `0` (default) | `0` (default) | Logging disabled — no file or console output |
| `0` | `1` | Console output to **stderr** at the configured level |
| `1` | `0` | File output to `ZEL_LOADER_LOG_DIR/ZEL_LOADER_LOG_FILE` |
| `1` | `1` | Console output to **stderr** — file path is ignored |

Default Log Pattern (Does not need to be set, please see below):
`ZEL_LOADER_LOG_PATTERN='[%Y-%m-%d %H:%M:%S.%e] [thread-id: %t] [%^%l%$] %v'`
> **Note:** When both `ZEL_ENABLE_LOADER_LOGGING=1` and `ZEL_LOADER_LOG_CONSOLE=1` are set,
> output goes to the console only. The file path configuration is not used. If persistent file
> capture is required, set `ZEL_LOADER_LOG_CONSOLE=0`.

Valid logging levels are trace, debug, info, warn, error, critical, off.
Logging is disabled by default but when enabled the default level is 'warn'.
The default log file is 'ze_loader.log' in '.oneapi_logs' in the current
user's home directory.
The log directory (`ZEL_LOADER_LOG_DIR`) is created automatically on first use if it does not exist.

The default log pattern includes timestamps, thread IDs, log levels, and messages.
You can customize the pattern using `ZEL_LOADER_LOG_PATTERN`. Common pattern flags:
- `%t` - thread id
- `%Y-%m-%d %H:%M:%S.%e` - timestamp with milliseconds
- `%l` - log level
- `%v` - the actual log message
See spdlog documentation for more pattern options.
## Log pattern

Default pattern (used when `ZEL_LOADER_LOG_PATTERN` is not set):
```
[%Y-%m-%d %H:%M:%S.%e] [thread-id: %t] [%^%l%$] %v
```

This feature is in early development and is preview only.
Supported pattern tokens:
- `%Y-%m-%d %H:%M:%S.%e` — timestamp with milliseconds (must appear as this exact sequence)
- `%t` — thread id
- `%P` — process id
- `%l` — log level label
- `%^` — begin color range (no-op when output is not a TTY)
- `%$` — end color range
- `%v` — log message

# Logging API calls
The Level Zero Loader will log all API calls whenever logging level is set to `trace` and
Expand All @@ -95,8 +118,10 @@ To print successful API call results, set
Otherwise, only error results will be printed in the API trace output.
NOTE: This will become the default behavior in future releases. for now, please set the env var to enable this logging feature.

By default logs will be written to the log file, as described above. To print the logs
to stderr instead, `ZEL_LOADER_LOG_CONSOLE=1` needs to be set.
By default logs will be written to the log file as described above. To print logs
to stderr instead of a file, set `ZEL_LOADER_LOG_CONSOLE=1`. Note that when
`ZEL_LOADER_LOG_CONSOLE=1`, the file path configuration is ignored — output goes
to the console only.

The API logging output format includes both function entry and exit information, showing parameter names on entry and parameter values with the result code on exit. Each log entry is timestamped and includes the thread-id, logger name, log level. Example output:

Expand Down
5 changes: 2 additions & 3 deletions scripts/templates/ze_loader_internal.h.mako
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ from templates import helper as th
#include "zer_ldrddi.h"

#include "loader/ze_loader.h"
#include "../utils/logging.h"
#include "spdlog/spdlog.h"
#include "../utils/ze_logger.h"
#include "source/lib/error_state.h"
namespace loader
{
Expand Down Expand Up @@ -139,7 +138,7 @@ namespace loader
bool instrumentationEnabled = false;
bool pciOrderingRequested = false;
dditable_t tracing_dditable = {};
std::shared_ptr<Logger> zel_logger;
std::shared_ptr<ZeLogger> zel_logger;
ze_driver_handle_t defaultZerDriverHandle = nullptr;
};

Expand Down
17 changes: 16 additions & 1 deletion source/layers/validation/ze_validation_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ namespace validation_layer
enableThreadingValidation = getenv_tobool( "ZE_ENABLE_THREADING_VALIDATION" );
verboseLogging = getenv_tobool( "ZEL_LOADER_LOGGING_ENABLE_SUCCESS_PRINT" );

logger = loader::createLogger();
// Point at the process-lifetime no-op logger until the loader calls
// zelLoaderSetLogger(). This is never null, so call sites need no null check.
// Thread-safety: zelLoaderSetLogger() writes this field exactly once on the
// init thread before zeDdiTable.exchange() makes the layer reachable.
logger = loader::noopLogger();
}

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -54,6 +58,17 @@ zelLoaderGetVersion(zel_component_version_t *version)
return ZE_RESULT_SUCCESS;
}

/// @brief Called by the loader immediately after dlopen to share its logger.
/// Replaces the no-op default so that validation-layer messages flow
/// through the same sink as the loader.
ZE_DLLEXPORT void ZE_APICALL
zelLoaderSetLogger(loader::ZeLogger *loaderLogger)
{
if (loaderLogger) {
validation_layer::context_t::getInstance().logger = loaderLogger;
}
}

#if defined(__cplusplus)
};
#endif
9 changes: 7 additions & 2 deletions source/layers/validation/ze_validation_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "zet_entry_points.h"
#include "zes_entry_points.h"
#include "zer_entry_points.h"
#include "logging.h"
#include "ze_logger.h"
#include "ze_to_string.h"
#include "zes_to_string.h"
#include "zet_to_string.h"
Expand Down Expand Up @@ -57,7 +57,12 @@ namespace validation_layer
std::vector<validationChecker *> validationHandlers;
std::unique_ptr<HandleLifetimeValidation> handleLifetime;

std::shared_ptr<loader::Logger> logger;
// Raw pointer — the loader owns the ZeLogger and guarantees it outlives
// the validation layer during normal operation (dlclose happens before
// zel_logger is destroyed in context_t::~context_t()). Using a raw pointer
// (rather than shared_ptr) avoids _Sp_counted_base::_M_release() being
// called during _dl_call_fini after the control block has been freed.
loader::ZeLogger *logger;

static context_t& getInstance() {
static context_t instance;
Expand Down
12 changes: 10 additions & 2 deletions source/lib/ze_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ namespace ze_lib
__zedlllocal context_t::context_t()
{
debugTraceEnabled = getenv_tobool( "ZE_ENABLE_LOADER_DEBUG_TRACE" );
if (debugTraceEnabled) {
std::cerr << "ZE_LOADER_DEBUG_TRACE: WARNING: ZE_ENABLE_LOADER_DEBUG_TRACE is deprecated and will be removed in a future release." << std::endl;
std::cerr << "ZE_LOADER_DEBUG_TRACE: WARNING: Use ZEL_LOADER_LOG_CONSOLE=1 with ZEL_LOADER_LOGGING_LEVEL=trace instead." << std::endl;
}
memset(&initialzeDdiTable, 0, sizeof(ze_dditable_t));
memset(&initialzetDdiTable, 0, sizeof(zet_dditable_t));
memset(&initialzesDdiTable, 0, sizeof(zes_dditable_t));
Expand Down Expand Up @@ -107,8 +111,12 @@ namespace ze_lib
loaderLibraryPath = readLevelZeroLoaderLibraryPath();
}
#endif
if (debugTraceEnabled)
debug_trace_message("Static Loader Using Loader Library Path: ", loaderLibraryPath);
if (debugTraceEnabled) {
if (loaderLibraryPath.empty())
debug_trace_message("Static Loader Using Loader Library Path: ", "Not set");
else
debug_trace_message("Static Loader Using Loader Library Path: ", loaderLibraryPath);
}
std::string loaderFullLibraryPath = create_library_path(MAKE_LIBRARY_NAME( "ze_loader", L0_LOADER_VERSION), loaderLibraryPath.c_str());
loader = LOAD_DRIVER_LIBRARY(loaderFullLibraryPath.c_str());

Expand Down
3 changes: 2 additions & 1 deletion source/lib/ze_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
#include "zer_ddi.h"
#include "layers/zel_tracing_api.h"
#include "layers/zel_tracing_ddi.h"
#include "../utils/logging.h"
#include "../utils/ze_logger.h"
#include "loader/ze_loader.h"
#include "ze_util.h"
#include <vector>
#include <map>
#include <mutex>
#include <atomic>
#include <typeinfo>
Expand Down
Loading
Loading