LexLeo 0.0.0-dev+f8e5087-dirty
Technical documentation
Loading...
Searching...
No Matches
logger_default.c
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-3.0-or-later
2 * Copyright (C) 2026 Sylvain Labopin
3 */
4
21
23
24#include "osal/time/osal_time.h"
25#include "osal/mem/osal_mem.h"
26
30
33
47
71 stream_t *stream,
72 const osal_time_ops_t *time_ops,
73 const osal_mem_ops_t *adapter_mem,
74 const logger_env_t *port_env)
75{
76 return (logger_default_env_t){
77 .stream = stream,
78 .time_ops = time_ops,
79 .adapter_mem = adapter_mem,
80 .port_env = *port_env
81 };
82}
83
112 stream_t *stream,
113 const osal_time_ops_t *time_ops)
114{
115 static const char TIMESTAMP_ERROR[] = "[timestamp error] ";
116
117 osal_time_t epoch_time;
118 osal_time_status_t now_st = time_ops->now(&epoch_time);
119 if (now_st != OSAL_TIME_STATUS_OK) {
121 size_t n =
123 stream,
124 TIMESTAMP_ERROR,
125 sizeof(TIMESTAMP_ERROR) - 1u,
126 &write_st);
127
128 if (write_st != STREAM_STATUS_OK ||
129 n != sizeof(TIMESTAMP_ERROR) - 1u) {
131 }
132
133 return LOGGER_STATUS_OK;
134 }
135
137 if (!logger_default_epoch_time_to_date(&date, &epoch_time)) {
139 size_t n =
141 stream,
142 TIMESTAMP_ERROR,
143 sizeof(TIMESTAMP_ERROR) - 1u,
144 &write_st);
145
146 if (write_st != STREAM_STATUS_OK ||
147 n != sizeof(TIMESTAMP_ERROR) - 1u) {
149 }
150
151 return LOGGER_STATUS_OK;
152 }
153
154 char buf[64];
155 int len =
156 snprintf(
157 buf,
158 sizeof(buf),
159 "[%04" PRId32 "-%02" PRId32 "-%02" PRId32
160 " %02" PRId32 ":%02" PRId32 ":%02" PRId32
161 " UTC+0] ",
162 date.year,
163 date.month,
164 date.day,
165 date.hour,
166 date.minute,
167 date.second
168 );
169
170 if (len < 0 || (size_t)len >= sizeof(buf)) {
172 }
173
175 size_t n = stream_write(stream, buf, (size_t)len, &write_st);
176
177 if (write_st != STREAM_STATUS_OK || n != (size_t)len) {
179 }
180
181 return LOGGER_STATUS_OK;
182}
183
209static logger_status_t logger_default_log(void *backend, const char *message)
210{
211 if (!message) {
213 }
214
215 LEXLEO_ASSERT(backend);
216
217 logger_default_t *logger_default = (logger_default_t *)backend;
218
219 LEXLEO_ASSERT(logger_default->stream && logger_default->time_ops);
220
221 logger_status_t write_timestamp_st =
223 logger_default->stream,
224 logger_default->time_ops);
225 if (write_timestamp_st != LOGGER_STATUS_OK) {
226 return write_timestamp_st;
227 }
228
230 size_t len = osal_strlen(message);
231
232 size_t n =
234 logger_default->stream,
235 message,
236 len,
237 &st
238 );
239 if (st != STREAM_STATUS_OK || n != len) {
241 }
242
243 if (logger_default->append_newline) {
244 n = stream_write(logger_default->stream, "\n", 1u, &st);
245
246 if (st != STREAM_STATUS_OK || n != 1u) {
248 }
249 }
250
251 return LOGGER_STATUS_OK;
252}
253
265static void logger_default_destroy(void *backend)
266{
267 if (!backend) {
268 return;
269 }
270
271 logger_default_t *logger_default = (logger_default_t *)backend;
272 LEXLEO_ASSERT(logger_default->mem && logger_default->mem->free);
273
274 logger_default->mem->free(logger_default);
275}
276
282 .destroy = logger_default_destroy,
283};
284
315 logger_t **out,
316 const logger_default_cfg_t *cfg,
317 const logger_default_env_t *env)
318{
319 if (!out || !cfg || !env) {
321 }
322
324 env->time_ops
325 && env->time_ops->now
326 && env->adapter_mem
327 && env->adapter_mem->malloc
328 && env->adapter_mem->free
329 && env->stream
330 );
331
332 logger_default_t *backend = env->adapter_mem->malloc(sizeof(*backend));
333 if (!backend) {
334 return LOGGER_STATUS_OOM;
335 }
336
337 backend->stream = env->stream;
338 backend->time_ops = env->time_ops;
339 backend->append_newline = cfg->append_newline;
340 backend->mem = env->adapter_mem;
341
342 logger_t *tmp = NULL;
343
344 logger_status_t st =
345 logger_create(&tmp, &DEFAULT_VTBL, (void *)backend, &env->port_env);
346
347 if (st != LOGGER_STATUS_OK) {
348 env->adapter_mem->free(backend);
349 return st;
350 }
351
352 *out = tmp;
353
354 return LOGGER_STATUS_OK;
355}
#define LEXLEO_ASSERT(expr)
Adapter-side API for constructing and binding logger_t objects.
logger_status_t logger_create(logger_t **out, const logger_vtbl_t *vtbl, void *backend, const logger_env_t *env)
Create a generic logger handle from adapter-provided backend bindings.
Definition logger.c:27
static const logger_vtbl_t DEFAULT_VTBL
Private backend vtable for logger_default.
static void logger_default_destroy(void *backend)
Private destroy implementation for the logger_default backend.
static logger_status_t logger_default_write_timestamp(stream_t *stream, const osal_time_ops_t *time_ops)
Write the logger_default timestamp prefix to the target stream.
logger_default_env_t logger_default_default_env(stream_t *stream, const osal_time_ops_t *time_ops, const osal_mem_ops_t *adapter_mem, const logger_env_t *port_env)
Build a default environment for the logger_default adapter.
static logger_status_t logger_default_log(void *backend, const char *message)
Private log implementation for the logger_default backend.
logger_status_t logger_default_create_logger(logger_t **out, const logger_default_cfg_t *cfg, const logger_default_env_t *env)
Create a logger instance backed by the logger_default adapter.
logger_default_cfg_t logger_default_default_cfg(void)
Return the default configuration for the logger_default adapter.
Composition Root API for wiring the logger_default adapter.
Private backend handle definition for the logger_default adapter.
bool logger_default_epoch_time_to_date(logger_default_utc_timestamp_t *out, const osal_time_t *time)
Convert an epoch-time value to a decomposed UTC timestamp.
Private UTC timestamp conversion helpers for the logger_default adapter.
logger_status_t
@ LOGGER_STATUS_OOM
@ LOGGER_STATUS_IO_ERROR
@ LOGGER_STATUS_OK
@ LOGGER_STATUS_INVALID
size_t osal_strlen(const char *s)
Definition osal_mem.c:35
osal_time_status_t
@ OSAL_TIME_STATUS_OK
Borrower-facing runtime operations for the stream port.
size_t stream_write(stream_t *s, const void *buf, size_t n, stream_status_t *st)
Write bytes to a stream.
Definition stream.c:38
stream_status_t
Public status codes used by the stream port.
@ STREAM_STATUS_OK
Configuration type for the logger_default adapter.
bool append_newline
Whether the adapter appends a trailing newline to emitted messages.
Injected dependencies for the logger_default adapter.
logger_env_t port_env
Borrowed logger port environment.
const osal_mem_ops_t * adapter_mem
Borrowed memory operations used for adapter-backend allocation.
stream_t * stream
Borrowed target stream used by the adapter.
const osal_time_ops_t * time_ops
Borrowed time operations used for timestamp generation.
Private backend handle for the logger_default adapter.
const osal_mem_ops_t * mem
const osal_time_ops_t * time_ops
Private UTC timestamp representation used by logger_default.
Runtime environment for the logger port.
Definition logger_env.h:34
Private handle structure for a logger_t.
Adapter dispatch table bound to a logger_t instance.
logger_status_t(* log)(void *backend, const char *message)
void *(* malloc)(size_t size)
void(* free)(void *ptr)
osal_time_status_t(* now)(osal_time_t *out)
Private handle structure for a stream_t.