Enhanced logging facade for Eiffel with structured fields and JSON output. Wraps EiffelStudio's logging library with a cleaner API.
simple_logger provides a SIMPLE_LOGGER class that enhances Eiffel's LOG_LOGGING_FACILITY with:
- Structured logging - Key-value fields in log entries
- JSON output - Machine-parseable format for log aggregation
- Child loggers - Inherit context fields from parent
- Enter/exit tracing - Automatic indentation for call traces
- Duration logging - Built-in timer for operation timing
- Clone the repository
- Set environment variable (one-time setup for all simple_* libraries):
SIMPLE_EIFFEL=D:\prod - Add to your ECF:
<library name="simple_logger" location="$SIMPLE_EIFFEL/simple_logger/simple_logger.ecf"/>| Library | Purpose | Environment Variable |
|---|---|---|
| simple_json | JSON output format | $SIMPLE_JSON |
local
log: SIMPLE_LOGGER
do
-- Basic logging
create log.make
log.info ("Application started")
log.warn ("Low disk space")
log.error ("Connection failed")
-- Change log level
log.set_level (log.Level_debug)
log.debug_log ("Verbose output")
endlocal
log: SIMPLE_LOGGER
fields: HASH_TABLE [ANY, STRING]
do
create log.make
-- With HASH_TABLE
create fields.make (2)
fields.put ("user123", "user_id")
fields.put (42, "order_id")
log.info_with ("Order processed", fields)
-- Output: 2025-12-06 14:30:00 INFO Order processed user_id=user123 order_id=42
-- With tuple array (convenience)
log.info_fields ("Login successful", << ["user", "alice"], ["ip", "192.168.1.1"] >>)
endlocal
log: SIMPLE_LOGGER
do
create log.make
log.set_json_output (True)
log.info ("Server started")
-- Output: {"timestamp":"2025-12-06T14:30:00Z","level":"info","message":"Server started"}
log.info_fields ("Request handled", << ["method", "GET"], ["path", "/api/users"], ["status", 200] >>)
-- Output: {"timestamp":"2025-12-06T14:30:01Z","level":"info","message":"Request handled","method":"GET","path":"/api/users","status":200}
endlocal
log, request_log: SIMPLE_LOGGER
do
create log.make
-- Create child with request context
request_log := log.child_with ("request_id", "req-abc-123")
-- All logs from request_log include request_id
request_log.info ("Processing request")
-- Output: 2025-12-06 14:30:00 INFO Processing request request_id=req-abc-123
request_log.info ("Request complete")
-- Output: 2025-12-06 14:30:01 INFO Request complete request_id=req-abc-123
endlocal
log: SIMPLE_LOGGER
do
create log.make_with_level ({SIMPLE_LOGGER}.Level_debug)
log.enter ("process_order")
log.info ("Validating order")
log.enter ("calculate_total")
log.debug_log ("Applying discount")
log.exit ("calculate_total")
log.exit ("process_order")
-- Output with indentation showing call hierarchy
endlocal
log: SIMPLE_LOGGER
timer: SIMPLE_LOG_TIMER
do
create log.make
timer := log.start_timer
-- Do some work
process_data
log.log_duration (timer, "Data processing complete")
-- Output: 2025-12-06 14:30:01 INFO Data processing complete duration_ms=152
endlocal
log: SIMPLE_LOGGER
do
-- Direct to file
create log.make_to_file ("app.log")
-- Or add file output to existing logger
create log.make
log.add_file_output ("app.log")
log.info ("This goes to console AND file")
end| Level | Constant | Use Case |
|---|---|---|
| DEBUG | Level_debug |
Verbose debugging information |
| INFO | Level_info |
Normal operational messages |
| WARN | Level_warn |
Warning conditions |
| ERROR | Level_error |
Error conditions |
| FATAL | Level_fatal |
System failure |
make- Console output, INFO levelmake_with_level (level)- Console output, specified levelmake_to_file (path)- File output
set_level (level)- Change minimum log levelset_json_output (enabled)- Enable/disable JSON formatadd_context (key, value)- Add persistent context fieldadd_file_output (path)- Add file output
debug_log (message),info (message),warn (message),error (message),fatal (message)*_with (message, fields)- With HASH_TABLE fieldsinfo_fields (message, tuples)- With tuple array
child (context)- Create child logger with contextchild_with (key, value)- Convenience for single field
enter (feature_name),exit (feature_name)- Call tracing
start_timer- Create timerlog_duration (timer, message)- Log with elapsed time
simple_logger uses LOG_LOGGING_FACILITY internally, so it's compatible with existing Eiffel logging infrastructure. You get the enhanced API while keeping compatibility with the standard library.
MIT License - Copyright (c) 2024-2025, Larry Rix