sirix / monolog
Monolog Factories for Mezzio
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
- monolog/monolog: ^3.10
- psr/container: ^1.0 || ^2.0.2
- psr/log: ^2.0 || ^3.0.2
- sirix/container-resolver: ^0.1.2
Requires (Dev)
- ext-json: *
- bamarni/composer-bin-plugin: ^1.9.1
- graylog2/gelf-php: ^2.0.0-beta.1
- mongodb/mongodb: ^2.1.2
- phpunit/phpunit: ^11.5.55
- ruflin/elastica: ^7.3.2
- sirix/redaction: ^1.3.1 || ^2.0
Suggests
- ext-amqp: Required when using the amqp handler with the ext-amqp exchange
- ext-curl: Required when using curl-based handlers such as ifttt, loggly, send_grid, slack_webhook, or telegram_bot
- ext-json: Required when using JSON-based Monolog formatters
- ext-mongodb: Required when using the mongo_db handler with MongoDB\Driver\Manager
- ext-openssl: Required when using SSL socket handlers such as fleep_hook, flowdock, or slack
- ext-sockets: Required when using the syslog_udp handler
- aws/aws-sdk-php: Required when using the dynamo_db or sqs handlers
- doctrine/couchdb: Required when using the doctrine_couch_db handler
- elastic/elasticsearch: Required when using the elasticsearch handler with the official Elasticsearch client v8
- elasticsearch/elasticsearch: Required when using the elasticsearch handler with the official Elasticsearch client v7
- graylog2/gelf-php: Required when using the gelf handler or formatter
- mongodb/mongodb: Required when using the mongo_db handler or formatter
- php-amqplib/php-amqplib: Required when using the amqp handler with php-amqplib
- php-console/php-console: Required when using the php_console handler
- predis/predis: Required when using redis handlers with Predis
- rollbar/rollbar: Required when using the rollbar handler
- ruflin/elastica: Required when using the elastica handler or formatter
- sirix/redaction: Required when using the redactor processor
- swiftmailer/swiftmailer: Required when using the mandrill handler
- symfony/mailer: Required when using the symfony_mailer handler
- symfony/mime: Required when using the symfony_mailer handler
README
Explicit Mezzio Monolog factory integration built around PSR-11, strict configuration, and predictable factories.
Requirements
- PHP 8.2+
- Monolog 3.x
- PSR-11 compatible container
- Mezzio config aggregation, or another container that can consume the provided factory map
Installation
composer require sirix/monolog
Register the config provider
In Mezzio applications that use laminas/laminas-component-installer, the provider is registered automatically during Composer install.
If your application does not use auto-discovery, add the provider to config/config.php manually:
<?php use Sirix\Monolog\ConfigProvider; return [ ConfigProvider::class, // ... ];
The provider registers logger, Monolog\Logger, and Psr\Log\LoggerInterface for the default logger service.
Default behavior
If no monolog configuration is provided, the package still exposes a safe default logger. The default services point to the default channel, that channel uses the Monolog name app, and it writes to a noop handler. Requesting Psr\Log\LoggerInterface is therefore safe even before application logging is configured; records are discarded until you define real handlers.
Defaults are applied per missing section. For example, a basic application can configure channels and handlers while omitting logger_services; the default logger service map will continue to point to the default channel.
Minimal configuration
Create config/autoload/monolog.global.php. The basic configuration does not need a logger_services section because logger, Monolog\Logger, and Psr\Log\LoggerInterface are registered for the default channel automatically:
<?php use Monolog\Level; use Sirix\Monolog\Enum\ConfigKey; use Sirix\Monolog\Enum\FormatterType; use Sirix\Monolog\Enum\HandlerType; use Sirix\Monolog\Enum\ProcessorType; return [ ConfigKey::Root->value => [ ConfigKey::Channels->value => [ 'default' => [ ConfigKey::Name->value => 'app', ConfigKey::Handlers->value => ['stream'], ConfigKey::Processors->value => ['psr_message'], ], ], ConfigKey::Handlers->value => [ 'stream' => [ ConfigKey::Type->value => HandlerType::Stream, ConfigKey::Formatter->value => 'line', ConfigKey::Options->value => [ 'stream' => 'php://stderr', 'level' => Level::Debug, ], ], ], ConfigKey::Formatters->value => [ 'line' => [ ConfigKey::Type->value => FormatterType::Line, ConfigKey::Options->value => [ 'format' => "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", 'date_format' => 'c', 'ignore_empty_context_and_extra' => true, ], ], ], ConfigKey::Processors->value => [ 'psr_message' => [ ConfigKey::Type->value => ProcessorType::PsrLogMessage, ], ], ], ];
Use the logger from the container:
<?php use Psr\Log\LoggerInterface; $logger = $container->get(LoggerInterface::class); $logger->info('User {user_id} logged in', ['user_id' => 42]);
Multiple logger services
Map any service id to a channel id with logger_services. Use a string value when the service should use the configured channel as-is. Use the array form when the service should reuse a configured channel stack but emit records with a different Monolog channel name.
<?php use Sirix\Monolog\Enum\ConfigKey; use Sirix\Monolog\Enum\HandlerType; return [ ConfigKey::Root->value => [ ConfigKey::LoggerServices->value => [ 'logger' => 'default', 'logger_audit' => 'audit', 'logger_crypto_transaction' => [ ConfigKey::Channel->value => 'audit', ConfigKey::Name->value => 'CryptoTransactionService', ], ], ConfigKey::Channels->value => [ 'default' => [ ConfigKey::Name->value => 'app', ConfigKey::Handlers->value => ['app_file'], ], 'audit' => [ ConfigKey::Name->value => 'audit', ConfigKey::Handlers->value => ['audit_file'], ], ], ConfigKey::Handlers->value => [ 'app_file' => [ ConfigKey::Type->value => HandlerType::Stream, ConfigKey::Options->value => [ 'stream' => 'data/log/app.log', ], ], 'audit_file' => [ ConfigKey::Type->value => HandlerType::Stream, ConfigKey::Options->value => [ 'stream' => 'data/log/audit.log', ], ], ], ], ];
Providing logger_services replaces the default service map for that section, so keep the logger entry when the default logger service should remain available. With the provided ConfigProvider, Monolog\Logger and Psr\Log\LoggerInterface are aliases to logger; keep the class-name entries too only if your container resolves those ids through LoggerFactory directly instead of aliases.
Register additional logger services with Sirix\Monolog\Factory\LoggerFactory in your container if your framework does not auto-wire them from the dependency config.
In the example above, logger_crypto_transaction reuses the audit channel's handlers and processors but writes CryptoTransactionService into Monolog's record channel field.
Built-in types
Handlers
amqpbrowser_consolebufferchrome_phpcouch_dbcubededuplicationdoctrine_couch_dbdynamo_dbelasticaelasticsearcherror_logfallback_groupfilterfingers_crossedfire_phpfleep_hookflowdockgelfgroupiftttinsight_opslog_entrieslogglylogmaticmandrillmongo_dbnative_mailernew_relicnoopnulloverflowphp_consoleprocesspsrpushoverredisredis_pub_subrollbarrotating_filesamplingsend_gridslackslack_webhooksocketsqsstreamsymfony_mailersyslogsyslog_udptelegram_bottestwhat_failure_groupzend_monitor
Formatters
linejsonhtmlnormalizerscalarlogstashwildfirechrome_phpgelfelasticaelasticsearchfluentdgoogle_cloud_logginglogglyflowdockmongo_dblogmaticsyslog
Processors
psr_log_messageclosure_contextgitintrospectionload_averagemercurialwebmemory_usagememory_peak_usageprocess_iduidhostnametagsredactor
Runtime notes
Configured loggers, handlers, formatters, and processors are cached for the container lifetime. In long-running workers, call Logger::reset() between jobs/messages so Monolog can flush buffers and release or reopen stateful resources.
Handlers are shared by handler id. If multiple channels reference the same handler id, they share the same handler instance and state. Use separate handler ids when buffered, deduplicated, or otherwise stateful handlers must be isolated.
Handler and processor order is preserved as written in configuration. This matters for bubble, wrapper handlers, filters, and processor chains.
A handler-local formatter requires a Monolog handler that supports formatters. Handler-local processors require a processable handler. Unsupported combinations fail fast with a configuration exception instead of being ignored.
For stream handlers, file_permission defaults to Monolog's default when omitted or set to null, so file permissions remain controlled by your process umask. use_locking defaults to false, matching Monolog. Enable it only when multiple processes write to the same file and you want flock() around each write.
Optional integrations
Many built-in handlers and formatters wrap Monolog integrations that require optional packages or PHP extensions. Install only the dependencies you use; Composer suggest lists the packages/extensions required by each optional integration. If an optional dependency is missing, the related factory fails with a configuration error when that handler, formatter, or processor is built.
Custom factories
Register custom factory classes under handler_factories, formatter_factories, or processor_factories.
<?php use App\Logging\AuditHandlerFactory; use Sirix\Monolog\Enum\ConfigKey; return [ ConfigKey::Root->value => [ ConfigKey::HandlerFactories->value => [ 'audit' => AuditHandlerFactory::class, ], ], ];
Custom factories must implement one of:
Sirix\Monolog\Handler\HandlerFactoryInterfaceSirix\Monolog\Formatter\FormatterFactoryInterfaceSirix\Monolog\Processor\ProcessorFactoryInterface
Documentation
Notes for 2.x
Version 2.x is a breaking release. The legacy MonologFactory, ChannelChanger, service managers, mappers, container-aware traits, and __invoke(array $options) factory API were removed. Use ConfigProvider, enum-backed configuration, and the strict factory interfaces instead.