--background_logresource--
Notes
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.
logAddEntryA()
Synopsis
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,
... );
Function
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'.
Result
Pointer to a logEntry structure if successful,
or NULL if the entry could not be created.
Example
struct logEntry *e = logAddEntryA(LOGM_Flag_Info, myLogHandle,
"filesystem", "disk.device", 42,
"Mounted volume %s", (RAWARG)"DH0:");
Notes
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.
Bugs
Kernel timestamp support is incomplete (marked TODO in source).
logAddListener()
Synopsis
struct logListenerHook * logAddListener(
struct MsgPort * mp,
ULONG msgmask );
Function
Register a message port for selected log notifications.
Result
A listener handle for logDeleteBroadcast() and logRemListener(),
or NULL for a NULL port or listener-handle allocation failure.
Notes
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.
Bugs
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.
logCmpStr()
Synopsis
int logCmpStr(
CONST_STRPTR str1,
CONST_STRPTR str2 );
Function
Compare two NUL-terminated strings using strcmp().
Result
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.
Notes
Comparison is case-sensitive and stops at the first unequal byte
or terminator. Neither string is modified or retained. NULL is not
accepted.
logCopyStr()
Synopsis
STRPTR logCopyStr(
CONST_STRPTR name );
Function
Allocate a copy of a NUL-terminated string.
Result
A caller-owned copy including the terminating NUL, or NULL for a
NULL source or allocation failure. Release the copy with FreeVec().
Notes
The source is not modified or retained. An empty source produces
an allocated empty string. Call from task context.
logCopyStrFmtA()
Synopsis
STRPTR logCopyStrFmtA(
CONST_STRPTR fmtstr,
RAWARG fmtdata );
STRPTR logCopyStrFmt(
CONST_STRPTR fmtstr,
... );
Function
Allocate a string formatted with RawDoFmt().
Result
A caller-owned NUL-terminated string, or NULL for a NULL format
or allocation failure. Release the string with FreeVec().
Notes
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.
Bugs
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.
logDeleteBroadcast()
Synopsis
void logDeleteBroadcast(
APTR listener,
APTR bMsg );
Function
Free one notification received by a listener.
Result
None. bMsg becomes invalid.
Notes
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.
logEventBroadcast()
Synopsis
VOID logEventBroadcast(
UBYTE ehmt,
APTR param1,
APTR param2 );
Function
Enqueue a notification for each matching listener.
Result
None. No delivery count or allocation-failure status is returned.
Notes
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.
Bugs
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.
logFinalise()
Synopsis
void logFinalise(
APTR logProvider );
Function
Locate registered producers by name. Cleanup is not implemented.
Notes
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.
Bugs
The finalization body is a placeholder. No resources are released.
logGetEntryAttrs()
Synopsis
IPTR logGetEntryAttrs(
APTR entryHandle,
struct TagItem * tags );
IPTR logGetEntryAttrsTags(
APTR entryHandle,
TAG tag, ... );
Function
Read selected attributes from a published log entry.
Result
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.
Notes
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.
Bugs
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>.
logInitialise()
Synopsis
APTR logInitialise(
APTR logProvider );
Function
Register a log producer and allocate its entry pool.
Result
A producer handle for logAddEntryA(), or NULL if the service task
is unavailable, logProvider is NULL, or pool creation fails.
Notes
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.
Bugs
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.
logLockEntries()
Synopsis
VOID logLockEntries(
ULONG flags );
Function
Acquire the resource's entry-list semaphore.
Result
None. Returns after acquiring the semaphore.
Notes
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.
Bugs
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.
logNextEntry()
Synopsis
APTR logNextEntry(
APTR * entryHandle );
Function
Advance a cursor through the global list of published log entries.
Result
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.
Notes
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.
logRawDoFmtA()
Synopsis
void logRawDoFmtA(
STRPTR buf,
ULONG len,
CONST_STRPTR fmtstr,
RAWARG fmtdata );
void logRawDoFmt(
STRPTR buf,
ULONG len,
CONST_STRPTR fmtstr,
... );
Function
Format RawDoFmt() arguments into a bounded character buffer.
Result
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.
Notes
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.
logRawDoFmtCBA()
Synopsis
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,
... );
Function
Run RawDoFmt() with a caller-supplied output routine.
Result
None. After formatting, buf[len - 1] is set to NUL. NULL buf,
NULL fmtstr or zero len suppresses the call and leaves buf unchanged.
Notes
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.
logRemEntry()
Synopsis
void logRemEntry(
struct logEntry * le );
Function
Unlink a published entry and queue its disposal by the service task.
Result
None. NULL has no effect.
Notes
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.
Bugs
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.
logRemListener()
Synopsis
VOID logRemListener(
APTR listener );
Function
Unregister a listener and delete its message pool.
Result
None. The handle and all allocations from its pool become invalid.
Notes
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.
Bugs
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.