1*523fa7a6SAndroid Build Coastguard Worker /*
2*523fa7a6SAndroid Build Coastguard Worker * Copyright (c) Meta Platforms, Inc. and affiliates.
3*523fa7a6SAndroid Build Coastguard Worker * All rights reserved.
4*523fa7a6SAndroid Build Coastguard Worker *
5*523fa7a6SAndroid Build Coastguard Worker * This source code is licensed under the BSD-style license found in the
6*523fa7a6SAndroid Build Coastguard Worker * LICENSE file in the root directory of this source tree.
7*523fa7a6SAndroid Build Coastguard Worker */
8*523fa7a6SAndroid Build Coastguard Worker
9*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/platform/log.h>
10*523fa7a6SAndroid Build Coastguard Worker
11*523fa7a6SAndroid Build Coastguard Worker #include <cstdio>
12*523fa7a6SAndroid Build Coastguard Worker
13*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/platform/compiler.h>
14*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/platform/platform.h>
15*523fa7a6SAndroid Build Coastguard Worker
16*523fa7a6SAndroid Build Coastguard Worker namespace executorch {
17*523fa7a6SAndroid Build Coastguard Worker namespace runtime {
18*523fa7a6SAndroid Build Coastguard Worker namespace internal {
19*523fa7a6SAndroid Build Coastguard Worker
20*523fa7a6SAndroid Build Coastguard Worker /**
21*523fa7a6SAndroid Build Coastguard Worker * Get the current timestamp to construct a log event.
22*523fa7a6SAndroid Build Coastguard Worker *
23*523fa7a6SAndroid Build Coastguard Worker * @retval Monotonically non-decreasing timestamp in system ticks.
24*523fa7a6SAndroid Build Coastguard Worker */
get_log_timestamp()25*523fa7a6SAndroid Build Coastguard Worker et_timestamp_t get_log_timestamp() {
26*523fa7a6SAndroid Build Coastguard Worker return et_pal_current_ticks();
27*523fa7a6SAndroid Build Coastguard Worker }
28*523fa7a6SAndroid Build Coastguard Worker
29*523fa7a6SAndroid Build Coastguard Worker // Double-check that the log levels are ordered from lowest to highest severity.
30*523fa7a6SAndroid Build Coastguard Worker static_assert(LogLevel::Debug < LogLevel::Info, "");
31*523fa7a6SAndroid Build Coastguard Worker static_assert(LogLevel::Info < LogLevel::Error, "");
32*523fa7a6SAndroid Build Coastguard Worker static_assert(LogLevel::Error < LogLevel::Fatal, "");
33*523fa7a6SAndroid Build Coastguard Worker static_assert(LogLevel::Fatal < LogLevel::NumLevels, "");
34*523fa7a6SAndroid Build Coastguard Worker
35*523fa7a6SAndroid Build Coastguard Worker /**
36*523fa7a6SAndroid Build Coastguard Worker * Maps LogLevel values to et_pal_log_level_t values.
37*523fa7a6SAndroid Build Coastguard Worker *
38*523fa7a6SAndroid Build Coastguard Worker * We don't share values because LogLevel values need to be ordered by severity,
39*523fa7a6SAndroid Build Coastguard Worker * and et_pal_log_level_t values need to be printable characters.
40*523fa7a6SAndroid Build Coastguard Worker */
41*523fa7a6SAndroid Build Coastguard Worker static constexpr et_pal_log_level_t kLevelToPal[size_t(LogLevel::NumLevels)] = {
42*523fa7a6SAndroid Build Coastguard Worker et_pal_log_level_t::kDebug,
43*523fa7a6SAndroid Build Coastguard Worker et_pal_log_level_t::kInfo,
44*523fa7a6SAndroid Build Coastguard Worker et_pal_log_level_t::kError,
45*523fa7a6SAndroid Build Coastguard Worker et_pal_log_level_t::kFatal,
46*523fa7a6SAndroid Build Coastguard Worker };
47*523fa7a6SAndroid Build Coastguard Worker
48*523fa7a6SAndroid Build Coastguard Worker // Double-check that the indices are correct.
49*523fa7a6SAndroid Build Coastguard Worker static_assert(
50*523fa7a6SAndroid Build Coastguard Worker kLevelToPal[size_t(LogLevel::Debug)] == et_pal_log_level_t::kDebug,
51*523fa7a6SAndroid Build Coastguard Worker "");
52*523fa7a6SAndroid Build Coastguard Worker static_assert(
53*523fa7a6SAndroid Build Coastguard Worker kLevelToPal[size_t(LogLevel::Info)] == et_pal_log_level_t::kInfo,
54*523fa7a6SAndroid Build Coastguard Worker "");
55*523fa7a6SAndroid Build Coastguard Worker static_assert(
56*523fa7a6SAndroid Build Coastguard Worker kLevelToPal[size_t(LogLevel::Error)] == et_pal_log_level_t::kError,
57*523fa7a6SAndroid Build Coastguard Worker "");
58*523fa7a6SAndroid Build Coastguard Worker static_assert(
59*523fa7a6SAndroid Build Coastguard Worker kLevelToPal[size_t(LogLevel::Fatal)] == et_pal_log_level_t::kFatal,
60*523fa7a6SAndroid Build Coastguard Worker "");
61*523fa7a6SAndroid Build Coastguard Worker
62*523fa7a6SAndroid Build Coastguard Worker /**
63*523fa7a6SAndroid Build Coastguard Worker * Log a string message.
64*523fa7a6SAndroid Build Coastguard Worker *
65*523fa7a6SAndroid Build Coastguard Worker * Note: This is an internal function. Use the `ET_LOG` macro instead.
66*523fa7a6SAndroid Build Coastguard Worker *
67*523fa7a6SAndroid Build Coastguard Worker * @param[in] level Log severity level.
68*523fa7a6SAndroid Build Coastguard Worker * @param[in] timestamp Timestamp (in system ticks) of the log event.
69*523fa7a6SAndroid Build Coastguard Worker * @param[in] filename Name of the source file creating the log event.
70*523fa7a6SAndroid Build Coastguard Worker * @param[in] function Name of the function creating the log event.
71*523fa7a6SAndroid Build Coastguard Worker * @param[in] line Source file line of the caller.
72*523fa7a6SAndroid Build Coastguard Worker * @param[in] format Format string.
73*523fa7a6SAndroid Build Coastguard Worker * @param[in] args Variable argument list.
74*523fa7a6SAndroid Build Coastguard Worker */
vlogf(ET_UNUSED LogLevel level,et_timestamp_t timestamp,const char * filename,ET_UNUSED const char * function,size_t line,const char * format,va_list args)75*523fa7a6SAndroid Build Coastguard Worker void vlogf(
76*523fa7a6SAndroid Build Coastguard Worker ET_UNUSED LogLevel level,
77*523fa7a6SAndroid Build Coastguard Worker et_timestamp_t timestamp,
78*523fa7a6SAndroid Build Coastguard Worker const char* filename,
79*523fa7a6SAndroid Build Coastguard Worker ET_UNUSED const char* function,
80*523fa7a6SAndroid Build Coastguard Worker size_t line,
81*523fa7a6SAndroid Build Coastguard Worker const char* format,
82*523fa7a6SAndroid Build Coastguard Worker va_list args) {
83*523fa7a6SAndroid Build Coastguard Worker #if ET_LOG_ENABLED
84*523fa7a6SAndroid Build Coastguard Worker
85*523fa7a6SAndroid Build Coastguard Worker // Maximum length of a log message.
86*523fa7a6SAndroid Build Coastguard Worker static constexpr size_t kMaxLogMessageLength = 256;
87*523fa7a6SAndroid Build Coastguard Worker char buf[kMaxLogMessageLength];
88*523fa7a6SAndroid Build Coastguard Worker size_t len = vsnprintf(buf, kMaxLogMessageLength, format, args);
89*523fa7a6SAndroid Build Coastguard Worker if (len >= kMaxLogMessageLength - 1) {
90*523fa7a6SAndroid Build Coastguard Worker buf[kMaxLogMessageLength - 2] = '$';
91*523fa7a6SAndroid Build Coastguard Worker len = kMaxLogMessageLength - 1;
92*523fa7a6SAndroid Build Coastguard Worker }
93*523fa7a6SAndroid Build Coastguard Worker buf[kMaxLogMessageLength - 1] = 0;
94*523fa7a6SAndroid Build Coastguard Worker
95*523fa7a6SAndroid Build Coastguard Worker et_pal_log_level_t pal_level =
96*523fa7a6SAndroid Build Coastguard Worker (int(level) >= 0 && level < LogLevel::NumLevels)
97*523fa7a6SAndroid Build Coastguard Worker ? kLevelToPal[size_t(level)]
98*523fa7a6SAndroid Build Coastguard Worker : et_pal_log_level_t::kUnknown;
99*523fa7a6SAndroid Build Coastguard Worker
100*523fa7a6SAndroid Build Coastguard Worker et_pal_emit_log_message(
101*523fa7a6SAndroid Build Coastguard Worker timestamp, pal_level, filename, function, line, buf, len);
102*523fa7a6SAndroid Build Coastguard Worker
103*523fa7a6SAndroid Build Coastguard Worker #endif // ET_LOG_ENABLED
104*523fa7a6SAndroid Build Coastguard Worker }
105*523fa7a6SAndroid Build Coastguard Worker
106*523fa7a6SAndroid Build Coastguard Worker } // namespace internal
107*523fa7a6SAndroid Build Coastguard Worker } // namespace runtime
108*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch
109