Universal PL/SQL logging library for Oracle Database 19c+
AxisLogger is a lightweight, universal logging library for Oracle PL/SQL.
It is designed to work in any Oracle environment — plain PL/SQL, Oracle APEX, Oracle Forms, Oracle Reports, REST services, or any other tool running on top of Oracle Database.
No dependencies. No configuration required to get started. One install script, and you're done.
- Simple, short API —
axl.err('message')oraxis_logger.error('message') - Log levels:
DEBUG,INFO,WARN,ERROR,FATAL - Automatic context capture — DB user, session, module, action, host
- Optional APEX context — app ID, page ID, session, APEX user
- Optional Oracle Forms context — via
DBMS_APPLICATION_INFO - Session timers — measure execution time with
timer_start/timer_stop - DML Audit — auto-generated triggers that log every INSERT / UPDATE / DELETE
- Configurable log levels per module (hierarchical resolution)
- Automatic purge via Oracle Scheduler
- Optional partitioning for high-volume environments
| Component | Version |
|---|---|
| Oracle Database | 19c or higher |
| Oracle APEX | optional, any version |
| Oracle Forms | optional, 12c |
| DBA access | required for initial install only |
@install/00_create_user.sql@install.sql-- Option A: grant to specific schema
GRANT axislog_user TO hr;
-- Option B: grant to everyone
GRANT EXECUTE ON axislog.axis_logger TO PUBLIC;
GRANT EXECUTE ON axislog.axl TO PUBLIC;-- Shortest possible syntax
axl.inf('Application started');
axl.err('Something went wrong');
axl.dbg('Processing record id=' || v_id);
-- Full syntax with logger name
axis_logger.info('Order confirmed', 'SHOP.ORDERS');
axis_logger.error('Payment failed id=' || p_id, 'SHOP.PAYMENTS');
-- Check if level is enabled before expensive operations
IF axis_logger.is_enabled('DEBUG', 'HR') THEN
axis_logger.debug('Data: ' || expensive_function(), 'HR');
END IF;
-- Timers
DECLARE
v_timer NUMBER;
BEGIN
v_timer := axis_logger.timer_start('fetch_report');
-- ... your code ...
axis_logger.timer_stop(v_timer);
END;
-- Session context (propagated to every log entry)
axis_logger.set_context('order_id', '12345');
axis_logger.set_context('user_role', 'ADMIN');-- Enable: auto-generates a trigger on the table
EXEC axis_logger_admin.enable_dml_audit('EMPLOYEES', 'HR');
-- Every INSERT / UPDATE / DELETE on HR.EMPLOYEES is now logged to AXIS_LOG_DML
-- Disable when no longer needed
EXEC axis_logger_admin.disable_dml_audit('EMPLOYEES', 'HR');-- Set global default
EXEC axis_logger_admin.set_level('*', 'WARN');
-- Override for specific module
EXEC axis_logger_admin.set_level('HR.EMPLOYEES', 'DEBUG');
-- Disable noisy logger
EXEC axis_logger_admin.disable('LEGACY.OLD_MODULE');| Procedure | Description |
|---|---|
axl.dbg(msg, logger) |
Log DEBUG |
axl.inf(msg, logger) |
Log INFO |
axl.wrn(msg, logger) |
Log WARN |
axl.err(msg, logger) |
Log ERROR |
axl.ftl(msg, logger) |
Log FATAL |
| Procedure / Function | Description |
|---|---|
debug / info / warn / error / fatal |
Log at given level |
is_enabled(level, logger) |
Returns TRUE if level is active |
set_context(key, value) |
Set session context key |
get_context(key) |
Get session context value |
clear_context |
Clear all session context |
timer_start(name) |
Start timer, returns timer ID |
timer_stop(timer_id) |
Stop timer and save result |
purge(days_to_keep) |
Delete old log entries |
| Procedure | Description |
|---|---|
set_level(logger, level) |
Set minimum log level |
enable(logger) |
Enable logger |
disable(logger) |
Disable logger |
set_destination(logger, dest) |
TABLE / DBMS_OUTPUT / BOTH |
enable_dml_audit(table, owner, ...) |
Create audit trigger |
disable_dml_audit(table, owner) |
Drop audit trigger |
purge_logs(older_than) |
Delete log entries |
purge_dml_logs(older_than) |
Delete DML audit entries |
| View | Description |
|---|---|
AXIS_LOG_V |
All logs, readable format |
AXIS_LOG_ERRORS_V |
ERROR and FATAL only, last 7 days |
AXIS_LOG_SESSION_V |
Logs for current Oracle session |
AXIS_LOG_STATS_V |
Aggregates per logger and level |
AXIS_LOG_TIMERS_V |
Timer results with percentiles |
AXIS_LOG_DML_V |
DML audit with diff format |
axislogger/
├── install/
│ ├── 00_create_user.sql # Run as SYSDBA
│ ├── 01_tables.sql
│ ├── 02_sequences.sql
│ ├── 03_indexes.sql
│ ├── 04_context.sql
│ ├── 05_packages_util.sql
│ ├── 06_packages_admin.sql
│ ├── 07_packages_core.sql
│ ├── 08_packages_dml.sql
│ ├── 09_packages_apex.sql
│ ├── 10_packages_axl.sql
│ ├── 11_views.sql
│ ├── 12_synonyms_grants.sql
│ ├── 13_config_defaults.sql
│ └── 14_scheduler.sql
├── uninstall/
│ └── drop_all.sql
├── test/
│ ├── test_basic.sql
│ ├── test_dml_audit.sql
│ ├── test_apex.sql
│ └── test_timers.sql
├── docs/
│ ├── INSTALL.md
│ ├── API.md
│ └── EXAMPLES.md
├── install.sql # Master install (run as AXISLOG)
├── uninstall.sql # Master uninstall
├── LICENSE
└── README.md
- ✅ Repository structure
- ✅ Create AXISLOG user script
- ✅ Master install / uninstall scripts
- ✅
.gitignore - ✅
README.md - ✅
LICENSE
- ❌
AXIS_LOG_CONFIG - ❌
AXIS_LOG - ❌
AXIS_LOG_TIMER - ❌
AXIS_LOG_DML_CONFIG - ❌
AXIS_LOG_DML - ❌ Sequences
- ❌ Indexes
- ❌ Call stack / error stack capture
- ❌ JSON builder (Oracle 19c
JSON_OBJECT) - ❌ Environment detection (APEX / Forms — graceful degradation)
- ❌
set_level / enable / disable - ❌ Hierarchical level resolution
- ❌ Package state cache
- ❌ Level constants
- ❌ Private
write_log - ❌ Session context capture
- ❌
debug / info / warn / error / fatal - ❌
is_enabled - ❌
set_context / clear_context - ❌
timer_start / timer_stop
- ❌
dbg / inf / wrn / err / ftl
- ❌ Synonyms for
AXIS_LOGGERandAXL - ❌ Role
AXISLOG_USER - ❌ Grants
- ❌
AXIS_LOG_V - ❌
AXIS_LOG_ERRORS_V - ❌
AXIS_LOG_SESSION_V - ❌
AXIS_LOG_STATS_V - ❌
AXIS_LOG_TIMERS_V - ❌
AXIS_LOG_DML_V
- ❌
AXIS_LOGGER_DML.log_change - ❌ Trigger DDL generator
- ❌
enable_dml_audit / disable_dml_audit
- ❌ APEX context auto-detection
- ❌ Oracle Forms via
DBMS_APPLICATION_INFO - ❌ REST / ORDS HTTP header context
- ❌
purge_logs / purge_dml_logs - ❌ Scheduler job (nightly purge)
- ❌ Optional partitioning script
- ❌
INSTALL.md - ❌
API.md - ❌
EXAMPLES.md - ❌
CHANGELOG.md - ❌
COMMENT ONon all database objects
Contributions are welcome. Please open an issue before submitting a pull request to discuss the change.
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes
- Open a Pull Request
MIT License — see LICENSE for details.
AxisLogger is not affiliated with or endorsed by Oracle Corporation.