--- Cannot embed stylesheet: [Errno 2] No such file or directory: '../../../aros.css' --->
This resource serves as a base interface to AROS's logging mechanisms.
It provides centralized collection and management of structured log messages
from system and application components, enabling uniform diagnostics and
analysis capabilities across the OS.
Messages are stored as dynamically allocated nodes
which are organized into two linked lists:
- A global list maintained by the log.resource itself
- A per-producer list
Entries are added using `logAddEntryA()` with a RawDoFmt-style format string
and metadata such as component, subcomponent, originator, and event ID.
Each entry stores:
- A human-readable formatted message (`le_Entry`)
- Producer and originator info (`lep_Producer`, `lectx_Originator`)
- Component tags (`le_Node.ln_Name`, `lep_Node.ln_Name`)
- Time/date stamp (`le_DateStamp`)
- Priority flags and event identifiers
Consumers may iterate over entries using `logNextEntry()` with an `entryHandle` pointer,
which is updated in place to walk through the list. Constants `LOGEntry_First` and
`LOGEntry_Last` mark the bounds of traversal.
Attributes of each entry can be queried with `logGetEntryAttrs()`, which takes a
taglist and returns selected fields such as LOGMA_Entry, LOGMA_Flags, LOGMA_Component,
and others.
`logRemEntry()` unlinks entries and may queue their disposal on the
service task. This does not guarantee complete deallocation.
`logLockEntries()` and `logUnlockEntries()` serialize cooperating readers
with insertion, but do not exclude every entry-removal path.
The log.resource is self-contained and allocates memory via the producer's
memory pool (`lrh_Pool`) to simplify cleanup and ownership tracking.
struct logEntry * logAddEntryA(
ULONG flags,
APTR loghandle,
STRPTR sub,
STRPTR src,
ULONG eventid,
STRPTR fmtstr,
RAWARG fmtdata );
struct logEntry * logAddEntry(
ULONG flags,
APTR loghandle,
STRPTR sub,
STRPTR src,
ULONG eventid,
STRPTR fmtstr,
... );
Creates and queues a new log entry associated with the given logging handle. The entry includes timestamp, event ID, optional subsystem/source strings, originator information, and a formatted message string built from 'fmtstr' and 'fmtdata'.
flags - Logging flags and priority level (LOGM_*). loghandle - Handle to an open log resource (struct LogResHandle *). sub - Optional subsystem string, may be NULL. src - Optional source string, may be NULL. eventid - User-supplied event identifier. fmtstr - Format string for the log message. fmtdata - Argument data matching the format string.
Pointer to a logEntry structure if successful, or NULL if the entry could not be created.
struct logEntry *e = logAddEntryA(LOGM_Flag_Info, myLogHandle,
"filesystem", "disk.device", 42,
"Mounted volume %s", (RAWARG)"DH0:");
The returned logEntry is owned by log.resource and should not be modified or freed by the caller. The timestamp source depends on availability of DOS, timer.device, or kernel facilities.
Kernel timestamp support is incomplete (marked TODO in source).
struct logListenerHook * logAddListener(
struct MsgPort * mp,
ULONG msgmask );
Register a message port for selected log notifications.
mp - Live message port, or NULL. Keep it valid until registration
has ended and all queued notifications have been handled.
msgmask - Event bits EHMF_* combined with LOGF_Flag_Type_* bits.
A listener handle for logDeleteBroadcast() and logRemListener(), or NULL for a NULL port or listener-handle allocation failure.
A notification matches only if msgmask contains its event bit and all of its entry-type bits. To receive all defined types and events, use LOGF_Flag_Type_All | EHMF_ALLEVENTS. Existing entries are not replayed. Registration order follows the port's priority at this call. Messages have type struct LogResBroadcastMsg. Remove them from the port with GetMsg(), then dispose of each with logDeleteBroadcast() using this listener handle. Do not ReplyMsg() or FreeVec() them. The target pointer is borrowed, not pinned by the message. Call from task context; registration may wait on a semaphore.
Creation of the listener's message pool is not checked. A non-NULL handle can therefore contain an unusable pool. Entry lifetime is not extended for queued messages; removal targets may already be freed when a listener receives them.
int logCmpStr(
CONST_STRPTR str1,
CONST_STRPTR str2 );
Compare two NUL-terminated strings using strcmp().
str1 - Non-NULL first string. str2 - Non-NULL second string.
Zero if equal, a negative value if str1 sorts before str2, or a positive value if it sorts after str2. Only the sign is specified.
Comparison is case-sensitive and stops at the first unequal byte or terminator. Neither string is modified or retained. NULL is not accepted.
STRPTR logCopyStr(
CONST_STRPTR name );
Allocate a copy of a NUL-terminated string.
name - Source string, or NULL.
A caller-owned copy including the terminating NUL, or NULL for a NULL source or allocation failure. Release the copy with FreeVec().
The source is not modified or retained. An empty source produces an allocated empty string. Call from task context.
STRPTR logCopyStrFmtA(
CONST_STRPTR fmtstr,
RAWARG fmtdata );
STRPTR logCopyStrFmt(
CONST_STRPTR fmtstr,
... );
Allocate a string formatted with RawDoFmt().
fmtstr - NUL-terminated RawDoFmt() format string, or NULL. fmtdata - RAWARG data matching fmtstr and the target ABI.
A caller-owned NUL-terminated string, or NULL for a NULL format or allocation failure. Release the string with FreeVec().
Formatting runs twice: once to calculate capacity and once to write the result. Keep the format, argument data and referenced strings unchanged across both passes. Call from task context.
The counting pass excludes newline characters, but the output pass writes them. Output containing newlines is therefore truncated; newlines are not simply removed. No truncation status is returned.
void logDeleteBroadcast(
APTR listener,
APTR bMsg );
Free one notification received by a listener.
listener - Live handle for the listener that received bMsg.
bMsg - Notification already removed from that listener's port,
not previously freed.
None. bMsg becomes invalid.
This frees only the notification, not its target entry. Use the matching listener because the message belongs to its private pool. Do not call after logRemListener(), which deletes that pool. The function performs no port removal, ReplyMsg(), origin check or listener locking; coordinate it with listener teardown.
VOID logEventBroadcast(
UBYTE ehmt,
APTR param1,
APTR param2 );
Enqueue a notification for each matching listener.
ehmt - Event index EHMB_*, not an EHMF_* mask.
param1 - Live log entry pointer used to read its type flags and
stored as the notification's lrbm_Target.
param2 - Reserved; currently ignored.
None. No delivery count or allocation-failure status is returned.
Matching requires all bits in
(entryFlags & LOGM_Flag_TypeMask) | (1L << ehmt)
to be present in the listener mask. Each message's lrbm_MsgType is
the event mask, not the event index. Messages are allocated from
the corresponding listener pool and sent asynchronously with PutMsg().
The caller must keep param1 valid while this function reads it.
The message does not retain or copy the entry. In particular, an
EHMF_REMENTRY target is an identity value, not a safe-to-dereference
entry. Call from task context; the listener semaphore may block.
Message allocation failure is not checked before dereferencing the result. All event types require a live entry in param1 because the implementation reads entry flags unconditionally; NULL is not valid even for START or STOP events.
void logFinalise(
APTR logProvider );
Locate registered producers by name. Cleanup is not implemented.
logProvider - Non-NULL pointer to an object beginning with a
struct Node whose ln_Name is a valid NUL-terminated
producer name. A producer handle has this prefix.
None.
The function compares names but does not unlink providers, remove entries, release pools or wait for pending events. Returning from this call does not establish that a producer has been shut down. Provider-list traversal is not protected internally.
The finalization body is a placeholder. No resources are released.
IPTR logGetEntryAttrs(
APTR entryHandle,
struct TagItem * tags );
IPTR logGetEntryAttrsTags(
APTR entryHandle,
TAG tag, ... );
Read selected attributes from a published log entry.
entryHandle - Live published entry handle, or NULL. Do not pass
LOGEntry_Last or a freed entry.
tags - Tag list whose ti_Data fields point to writable destinations
of the types listed below.
LOGMA_Flags (ULONG *)
Entry flags with the private high-byte flags removed.
LOGMA_DateStamp (struct DateStamp **)
Pointer to the entry's stored timestamp.
LOGMA_EventID (ULONG *)
Event identifier supplied by the producer.
LOGMA_Origin (char **)
Recorded originating task description.
LOGMA_Component (char **)
Producer name. Written only if a producer is associated.
LOGMA_SubComponent (char **)
Subcomponent string supplied when the entry was added.
LOGMA_LogTag (char **)
Source/tag string supplied when the entry was added.
LOGMA_Entry (char **)
Formatted message text.
The number of attributes written. Zero is returned for NULL, a node not marked NT_LOGENTRY, or failure to open utility.library. Unsupported tags are ignored. Only the first occurrence of each supported tag is processed; skipped destinations are unchanged.
Use normal tag-list termination and control tags. String and date results point into resource-owned storage; they are not copies. Do not modify or free them. Individual string results may be NULL. Hold the entry lock and coordinate entry removal before reading or copying these values. The function does not acquire the entry lock and may open utility.library; call from task context.
LOGMA_Level and LOGMA_Type are not handled. Obtain their bits from LOGMA_Flags instead. The public LOGMA_Type macro is also malformed in this version of <resources/log.h>.
APTR logInitialise(
APTR logProvider );
Register a log producer and allocate its entry pool.
logProvider - Non-NULL pointer to an object beginning with a
struct Node. ln_Name identifies the producer and
should point to a NUL-terminated name.
A producer handle for logAddEntryA(), or NULL if the service task is unavailable, logProvider is NULL, or pool creation fails.
The name is copied; the provider object is not retained. The resource owns the returned handle and pool. Do not free them with FreeVec() or DeletePool(). Call from task context. Provider-list updates are not protected internally; serialize registrations.
Handle allocation is not checked before dereferencing its result. Name-copy failure can leave a registered handle without a name. logFinalise() does not yet release the handle or its pool.
VOID logLockEntries(
ULONG flags );
Acquire the resource's entry-list semaphore.
flags - LLF_READ or LLF_WRITE. Currently ignored.
None. Returns after acquiring the semaphore.
Call from task context where waiting is permitted. Both flag values acquire the same exclusive semaphore. Balance each acquisition with logUnlockEntries() in the same task. Hold the lock while traversing entries and inspecting borrowed attributes. This serializes cooperating users and the service task's insertion path; it does not establish complete entry-lifetime safety.
logRemEntry() does not acquire this semaphore. The service task's removal and deallocation path does not acquire it either. A held lock alone cannot protect against every concurrent removal.
APTR logNextEntry(
APTR * entryHandle );
Advance a cursor through the global list of published log entries.
entryHandle - Pointer to a writable APTR cursor. Initialize it to
LOGEntry_First; subsequently retain each returned
entry or LOGEntry_Last. NULL is accepted.
The next entry, also written to *entryHandle, or LOGEntry_Last for an empty list or end of traversal. Passing LOGEntry_Last leaves it unchanged; it does not return the final entry. A NULL cursor pointer returns NULL.
Returned entries are borrowed. Hold logLockEntries() during traversal and coordinate removal separately as described there. Only pass live published entries from this list as cursors; a stale address is not made safe by the node-type check. This function does not acquire a lock or allocate storage.
void logRawDoFmtA(
STRPTR buf,
ULONG len,
CONST_STRPTR fmtstr,
RAWARG fmtdata );
void logRawDoFmt(
STRPTR buf,
ULONG len,
CONST_STRPTR fmtstr,
... );
Format RawDoFmt() arguments into a bounded character buffer.
buf - Writable buffer of at least len bytes. len - Buffer capacity, including the terminator. fmtstr - NUL-terminated RawDoFmt() format string. fmtdata - RAWARG data matching fmtstr and the target ABI.
None. With non-NULL buf and fmtstr and len greater than zero, output is NUL-terminated and truncated to at most len - 1 bytes. Otherwise the buffer is unchanged.
The formatter still processes the complete format after the buffer fills. No required-length or truncation result is returned. The buffer is caller-owned; no storage is allocated. Use RawDoFmt() format and argument conventions, not a printf() va_list.
void logRawDoFmtCBA(
STRPTR buf,
ULONG len,
VOID_FUNC cbfunc,
void * cbdata,
CONST_STRPTR fmtstr,
RAWARG fmtdata );
void logRawDoFmtCB(
STRPTR buf,
ULONG len,
VOID_FUNC cbfunc,
void * cbdata,
CONST_STRPTR fmtstr,
... );
Run RawDoFmt() with a caller-supplied output routine.
buf - Writable buffer of at least len bytes. len - Capacity of buf; must be greater than zero to invoke output. cbfunc - RawDoFmt()-compatible output routine. cbdata - Output routine's context, passed unchanged to RawDoFmt(). fmtstr - NUL-terminated RawDoFmt() format string. fmtdata - RAWARG data matching fmtstr and the target ABI.
None. After formatting, buf[len - 1] is set to NUL. NULL buf, NULL fmtstr or zero len suppresses the call and leaves buf unchanged.
buf and len are not passed to the output routine and do not bound its writes. The routine must implement its own capacity checks through cbdata. It receives RawDoFmt() output, including the final NUL, using the RawDoFmt callback ABI. Execution is synchronous; context and output storage must remain valid until return. Any allocation, waiting or side effects of the callback are the callback's responsibility.
void logRemEntry(
struct logEntry * le );
Unlink a published entry and queue its disposal by the service task.
le - Live published entry from log.resource, removed at most once,
or NULL. An entry still awaiting publication is not valid here.
None. NULL has no effect.
The function removes both global and producer linkage as applicable. If the service task is running, it queues EHMB_REMENTRY and returns without waiting for notification or deallocation. Treat the handle and all borrowed attributes as invalid after requesting removal. Do not free the entry yourself. List removal uses Forbid()/Permit(), not the entry semaphore. Callers must coordinate removal with readers; logLockEntries() alone does not exclude this path.
No node-state or duplicate-removal check is made. If the service task has stopped, the entry is unlinked but not freed. The service task does not free the copied subcomponent string. Its removal notification contains a pointer that it then frees without waiting for listeners to consume the message.
VOID logRemListener(
APTR listener );
Unregister a listener and delete its message pool.
listener - Live handle returned by logAddListener(). NULL and
previously removed handles are invalid.
None. The handle and all allocations from its pool become invalid.
The listener lock serializes unregistration with broadcasts. It does not drain the destination port or wait for consumers. Before removal, coordinate publishers and consumers so no new notification can arrive and no queued or retained message remains. Dispose of messages with logDeleteBroadcast() while the handle is still valid. The message port itself remains caller-owned. Call from task context; acquiring the listener lock may wait.
Deleting the pool invalidates outstanding messages even if they remain linked on the destination port. The API has no separate stop-delivery operation that preserves the pool for draining. Draining the port while broadcasts continue is not a safe shutdown protocol.
VOID logUnlockEntries(
ULONG flags );
Release the semaphore acquired by logLockEntries().
flags - LLF_READ or LLF_WRITE. Currently ignored.
None.
The calling task must own a matching acquisition. Do not use this call to release another task's lock. Borrowed entry pointers are not reference-counted and must not be assumed valid after unlocking.