Skip to content

LogEvent

Canonical source: protos/lib/logging/LogEvent.protos at locked revision e99b712ecf658a527b1fe82c8beba2c1286d8dc9.

// THE LICENSED WORK IS PROVIDED UNDER THE TERMS OF THE ADAPTIVE PUBLIC LICENSE
// ("LICENSE") AS FIRST COMPLETED BY: Guillermo Adrián Molina. ANY USE, PUBLIC
// DISPLAY, PUBLIC PERFORMANCE, REPRODUCTION OR DISTRIBUTION OF, OR PREPARATION OF
// DERIVATIVE WORKS BASED ON, THE LICENSED WORK CONSTITUTES RECIPIENT'S ACCEPTANCE
// OF THIS LICENSE AND ITS TERMS, WHETHER OR NOT SUCH RECIPIENT READS THE TERMS OF
// THE LICENSE. "LICENSED WORK" AND "RECIPIENT" ARE DEFINED IN THE LICENSE. A COPY
// OF THE LICENSE IS LOCATED IN THE TEXT FILE ENTITLED "LICENSE.TXT" ACCOMPANYING
// THE CONTENTS OF THIS FILE. IF A COPY OF THE LICENSE DOES NOT ACCOMPANY THIS
// FILE, A COPY OF THE LICENSE MAY ALSO BE OBTAINED AT THE FOLLOWING WEB SITE:
// https://github.com/guillermomolina/protos
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
// the specific language governing rights and limitations under the License.
//! Immutable structured log events. An event is a frozen ordinary object with
//! a `level` slot holding a canonical `std:logging/Level`, a String `message`,
//! a frozen standard Map `fields` of structured data, an `error` slot holding
//! the attached Error or `null`, and a `timestamp` slot holding a
//! `std:datetime/Instant` or `null`. Every event has all five slots; an event
//! without a time has `timestamp` `null`.
//!
//! Structured data is ordinary Protos data drawn only from `null`, `true`,
//! `false`, Strings, Integers, Floats, standard Arrays, and normal standard
//! Maps whose keys are Strings, nested to any depth. An event never converts
//! another value to a String and never invokes its behavior; such a value
//! signals an Error instead. Field order is not part of an event's meaning.
//!
//! An event owns a snapshot of its fields: every Array and Map is copied and
//! the copy frozen, so later mutation of the supplied data, at any depth, does
//! not change the event. Core freeze is shallow, which is why the copy is
//! taken at every level. A supplied Array or Map that contains itself, directly
//! or indirectly, signals an Error.
//!
//! The attached Error is kept by reference: it is neither copied, mutated,
//! signalled, nor converted. The timestamp is kept by reference as supplied;
//! an event never reads a current time. An event carries no formatter, sink,
//! writer, clock, or other ambient authority.
//!
//! Every event's immediate delegation parent is this module, the canonical
//! event factory and prototype. `recognizes` accepts exactly the events of
//! this family: frozen objects whose immediate parent is this module, whose
//! local slots are exactly `level`, `message`, `fields`, `error`, and
//! `timestamp`, and whose slots hold valid event state. Recognition reads that
//! state directly, so it never invokes behavior of the candidate; an object
//! that merely has similar slots is not an event.
/// Answers a fresh frozen event for `level`, `message`, `fields`, `error`, and
/// `timestamp`.
/// `level` must be a canonical level and `message` a String. `fields` must be
/// a normal standard Map of structured data, or `null` for no fields; the
/// event's `fields` slot is always a frozen Map snapshot. `error` must be an
/// object that delegates to `Error`, or `null`. `timestamp` must be an instant
/// recognized by `std:datetime/Instant`, or `null`, the default, for an event
/// without a time. Any other argument signals an Error.
call: ((facility) => (level, message, fields, error, timestamp = null) => {
LogEvent: import("std:logging/LogEvent")
Instant: import("std:datetime/Instant")
Level: import("std:logging/Level")
Arrays: import("std:collections/Array")
Level.compare(level, level)
String.recognizes(message).ifFalse(() => {
Error().signal()
})
// An attached Error is recognized through its delegation chain, the
// relation Error handler matching uses, read without invoking any behavior
// of the candidate; the Error prototype itself is not an attachable Error.
((error === null) || facility.isAttachableError(error)).ifFalse(() => {
Error().signal()
})
// An empty matcher Map recognizes exactly normal standard Maps without
// invoking any behavior of the candidate.
mapMatcher: %{}
isMap: (value) => {
mapMatcher.match(value) === true
}
active: IdentityMap()
snapshot: null
snapshot = (value) => {
result: value
handled: (value === null) ||
(value === true) ||
(value === false) ||
String.recognizes(value) ||
Integer.recognizes(value) ||
Float.recognizes(value)
handled.ifFalse(() => {
Array.recognizes(value).ifTrue(() => {
active.containsKey(value).ifTrue(() => {
Error().signal()
})
active[value] = true
copy: Arrays.map(value, (element) => snapshot(element))
copy.freeze()
active.remove(value)
result = copy
handled = true
})
})
handled.ifFalse(() => {
isMap(value).ifTrue(() => {
active.containsKey(value).ifTrue(() => {
Error().signal()
})
active[value] = true
copy: Map()
value.each((key, item) => {
String.recognizes(key).ifFalse(() => {
Error().signal()
})
copy[key] = snapshot(item)
})
copy.freeze()
active.remove(value)
result = copy
handled = true
})
})
handled.ifFalse(() => {
Error().signal()
})
result
}
eventFields: Map()
eventFields.freeze()
(fields === null).ifFalse(() => {
isMap(fields).ifFalse(() => {
Error().signal()
})
eventFields = snapshot(fields)
})
event: (LogEvent) {
level: level
message: message
fields: eventFields
error: error
timestamp: timestamp
}
event.freeze()
// Recognition also validates the timestamp, reading it without invoking
// any behavior of the candidate.
facility.recognizes(event, LogEvent, Instant).ifFalse(() => {
Error().signal()
})
event
})(_logEventFacility)
/// Answers `true` exactly when `value` is an event of this family: a frozen
/// object whose immediate delegation parent is this module, whose local slots
/// are exactly `level`, `message`, `fields`, `error`, and `timestamp`, and
/// whose `level` is a canonical level, `message` a String, `fields` a frozen
/// standard Map of structured data frozen at every depth, `error` an Error or
/// `null`, and `timestamp` a `std:datetime/Instant` or `null`.
/// Answers `false` for any other value, including this module. The candidate
/// is neither copied, converted, nor sent any message.
recognizes: ((facility) => (value) => {
facility.recognizes(value, import("std:logging/LogEvent"), import("std:datetime/Instant"))
})(_logEventFacility)
// The runtime-provisioned facility is captured privately above; it is not
// module surface.
context.removeSlot("_logEventFacility")

← logging family · Standard-library source