{"id":19763872,"url":"https://github.com/hypemc/loggable-command-bundle","last_synced_at":"2025-10-11T15:31:56.183Z","repository":{"id":40312001,"uuid":"328867002","full_name":"HypeMC/loggable-command-bundle","owner":"HypeMC","description":"Symfony bundle which creates a dedicated Monolog log file for each command or message handler","archived":false,"fork":false,"pushed_at":"2024-09-14T19:22:47.000Z","size":103,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"1.x","last_synced_at":"2025-04-30T14:33:22.054Z","etag":null,"topics":["bundle","cli","console","log","logger","logging","monolog","php","symfony","symfony-bundle","symfony-console","symfony-messenger"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HypeMC.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-12T04:00:56.000Z","updated_at":"2024-09-14T18:49:53.000Z","dependencies_parsed_at":"2024-01-02T05:34:17.124Z","dependency_job_id":"5fb3a448-89b5-4b8c-8bd4-a312db3c69b1","html_url":"https://github.com/HypeMC/loggable-command-bundle","commit_stats":{"total_commits":37,"total_committers":1,"mean_commits":37.0,"dds":0.0,"last_synced_commit":"50c3d0ced8ca23f65c9b9ffd938292293c083eae"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/HypeMC/loggable-command-bundle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HypeMC%2Floggable-command-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HypeMC%2Floggable-command-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HypeMC%2Floggable-command-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HypeMC%2Floggable-command-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HypeMC","download_url":"https://codeload.github.com/HypeMC/loggable-command-bundle/tar.gz/refs/heads/1.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HypeMC%2Floggable-command-bundle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007604,"owners_count":26084334,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundle","cli","console","log","logger","logging","monolog","php","symfony","symfony-bundle","symfony-console","symfony-messenger"],"created_at":"2024-11-12T04:11:24.544Z","updated_at":"2025-10-11T15:31:56.165Z","avatar_url":"https://github.com/HypeMC.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BizkitLoggableCommandBundle\n\n[![Build Status](https://github.com/HypeMC/loggable-command-bundle/workflows/CI/badge.svg)](https://github.com/HypeMC/loggable-command-bundle/actions)\n[![Latest Stable Version](https://poser.pugx.org/bizkit/loggable-command-bundle/v/stable)](https://packagist.org/packages/bizkit/loggable-command-bundle)\n[![License](https://poser.pugx.org/bizkit/loggable-command-bundle/license)](https://packagist.org/packages/bizkit/loggable-command-bundle)\n[![Code Coverage](https://codecov.io/gh/HypeMC/loggable-command-bundle/branch/1.x/graph/badge.svg)](https://codecov.io/gh/HypeMC/loggable-command-bundle)\n\nSymfony bundle which creates a dedicated Monolog log file for each command or message handler.\n\n## Features\n\n* Dynamically creates a dedicated Monolog file handler for each command or message handler\n* Uses Monolog's console handler to display the output inside a terminal\n* Supports using Monolog's stream or rotating file handlers \u0026 creating custom handler factories\n* Automatically excludes the configured Monolog channel from all other handlers with exclusive channels\n* Allows per command configuration through the use of PHP 8 attributes or Doctrine annotations\n* Supports configuring which output stream should be used by certain log levels (`stdout` or `stderr`)\n\n## Requirements\n\n* [PHP 7.2](http://php.net/releases/7_2_0.php) or greater\n* [Symfony 4.4](https://symfony.com/roadmap/4.4) or [Symfony 5.2](https://symfony.com/roadmap/5.2) or greater\n\n## Installation\n\n1. Require the bundle with [Composer](https://getcomposer.org/):\n\n    ```sh\n    composer require bizkit/loggable-command-bundle\n    ```\n\n1. Create the bundle configuration file under `config/packages/bizkit_loggable_command.yaml`. Here is a reference\n   configuration file:\n\n    ```yaml\n    bizkit_loggable_command:\n\n        # The name of the channel used by the console \u0026 file handlers.\n        channel_name:         loggable_output\n\n        # Configuration options for the console handler.\n        console_handler_options:\n\n            # The minimum level at which the output is sent to stderr instead of stdout.\n            stderr_threshold:     ERROR\n            bubble:               true\n            verbosity_levels:\n                VERBOSITY_QUIET:      ERROR\n                VERBOSITY_NORMAL:     WARNING\n                VERBOSITY_VERBOSE:    NOTICE\n                VERBOSITY_VERY_VERBOSE: INFO\n                VERBOSITY_DEBUG:      DEBUG\n            console_formatter_options:\n                format:               \"[%%datetime%%] %%start_tag%%%%level_name%%%%end_tag%% %%message%%\\n\"\n            formatter:            null\n\n        # Configuration options for the file handler.\n        file_handler_options:\n\n            # The path where the log files are stored.\n            # A {filename} \u0026 {date} placeholders are available which get resolved to the name of the log \u0026 current date.\n            # The date format can be configured using the \"date_format\" option.\n            path:                 '%kernel.logs_dir%/console/{filename}.log' # Example: '%kernel.logs_dir%/console/{filename}/{date}.log'\n\n            # The name of the file handler factory to use.\n            type:                 stream\n            level:                DEBUG\n            bubble:               true\n            include_stacktraces:  false\n            formatter:            null\n            file_permission:      null\n            use_locking:          false\n            max_files:            0\n            filename_format:      '{filename}-{date}'\n            date_format:          Y-m-d\n\n            # Extra options that can be used in custom handler factories.\n            extra_options:        []\n\n                # Examples:\n                # my_option1:          'some value'\n                # my_option2:          true\n\n            # Enables configuring services with the use of an annotation, requires the Doctrine Annotation library.\n            enable_annotations:   false\n\n        # Configuration option used by both handlers.\n        process_psr_3_messages:\n\n            # Examples:\n            # - false\n            # - { enabled: false }\n            # - { date_format: Y-m-d, remove_used_context_fields: true }\n            enabled:              true\n            date_format:          ~\n            remove_used_context_fields: ~\n    ```\n\n1. Enable the bundle in `config/bundles.php` by adding it to the array:\n\n    ```php\n    Bizkit\\LoggableCommandBundle\\BizkitLoggableCommandBundle::class =\u003e ['all' =\u003e true],\n    ```\n\n## Usage\n\nThe bundle provides a way to log the output of a [Symfony Command](https://symfony.com/doc/current/console.html)\nor [Symfony Messenger's](https://symfony.com/doc/current/messenger.html#creating-a-message-handler) message handler into\na dedicated file by dynamically creating a [Monolog](https://github.com/Seldaek/monolog) file handler \u0026 logger for each\nservice. Supported file handlers are the `stream` \u0026 `rotating_file` handlers. To use other file handlers,\na [custom handler factory](#handler-factories) must be implemented \u0026 registered.\n\nThe output logger also uses a console handler to display the output inside a terminal. The `stderr_threshold` option can\nbe used to set the log level at which the output is start being sent to the `stderr` stream instead of the `stdout`.\n\nOther Monolog handlers can be added to the output logger as well as described in\nthe [dedicated section](#adding-other-monolog-handlers-to-the-output-logger).\n\n### Command\n\nThe simplest way to enable output logging in a Symfony Command is by extending the `LoggableCommand` class. The output\nlogger can be accessed through the `$outputLogger` property. By default, the name of the log file will be the snake\ncased version of the command name, e.g. `app_my_loggable`.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\Command\\LoggableCommand;\n\nclass MyLoggableCommand extends LoggableCommand\n{\n    protected static $defaultName = 'app:my-loggable';\n\n    protected function execute(InputInterface $input, OutputInterface $output): int\n    {\n        $this-\u003eoutputLogger-\u003edebug('Debug');\n        $this-\u003eoutputLogger-\u003enotice('Notice');\n\n        // ...\n    }\n}\n```\n\nInstead of extending the `LoggableCommand` class, you can also use the `LoggableOutputTrait` with\nthe `LoggableOutputInterface`. This is useful when you have a custom base command class.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\LoggableOutputInterface;\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\LoggableOutputTrait;\n\nclass MyLoggableCommand extends MyBaseCommand implements LoggableOutputInterface\n{\n    use LoggableOutputTrait;\n\n    protected function execute(InputInterface $input, OutputInterface $output): int\n    {\n        // ...\n    }\n}\n```\n\n### Message handler\n\nOutput logging can also be used with Symfony Messenger's message handlers by implementing the `LoggableOutputInterface`.\nThe name of the log file will be the snake cased version of the classname, e.g. `my_message_handler`. A custom name can\nbe provided by implementing the `NamedLoggableOutputInterface` instead.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\LoggableOutputTrait;\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\NamedLoggableOutputInterface;\nuse Symfony\\Component\\Messenger\\Handler\\MessageHandlerInterface;\n\nclass MyMessageHandler implements MessageHandlerInterface, NamedLoggableOutputInterface\n{\n    use LoggableOutputTrait;\n\n    public function __invoke(MyMessage $myMessage): void\n    {\n        $this-\u003eoutputLogger-\u003eerror('Error');\n        $this-\u003eoutputLogger-\u003einfo('Info');\n    }\n\n    public function getOutputLogName(): string\n    {\n        return 'my_log_name';\n    }\n}\n```\n\n### PHP 8 attribute\n\nThe default configuration can be overridden for each individual command or message handler by using the `LoggableOutput`\n[PHP attribute](https://www.php.net/manual/en/language.attributes.overview.php). Among other things, it allows you to\nchange which Monolog file handler is used by the output logger.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\Command\\LoggableCommand;\nuse Bizkit\\LoggableCommandBundle\\ConfigurationProvider\\Attribute\\LoggableOutput;\n\n#[LoggableOutput(filename: 'my_custom_name', type: 'rotating_file')]\nclass MyLoggableCommand extends LoggableCommand\n{\n    protected function execute(InputInterface $input, OutputInterface $output): int\n    {\n        // ...\n    }\n}\n```\n\nThe PHP attribute can also be used as an alternative way to provide a custom name for the log file, in which case\nimplementing the `NamedLoggableOutputInterface` is not necessary.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\ConfigurationProvider\\Attribute\\LoggableOutput;\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\LoggableOutputInterface;\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\LoggableOutputTrait;\nuse Symfony\\Component\\Messenger\\Handler\\MessageHandlerInterface;\n\n#[LoggableOutput(filename: 'my_log_name')]\nclass MyMessageHandler implements MessageHandlerInterface, LoggableOutputInterface\n{\n    use LoggableOutputTrait;\n\n    public function __invoke(MyMessage $myMessage): void\n    {\n        // ...\n    }\n}\n```\n\nAttribute options are inherited from all parent classes that have the PHP attribute declared. In case both a parent \u0026 a\nchild class have the same option defined, the one from the child class has precedence.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\ConfigurationProvider\\Attribute\\LoggableOutput;\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\LoggableOutputInterface;\nuse Bizkit\\LoggableCommandBundle\\LoggableOutput\\LoggableOutputTrait;\nuse Symfony\\Component\\Messenger\\Handler\\MessageHandlerInterface;\n\n#[LoggableOutput(path: '%kernel.logs_dir%/messenger/{filename}.log')]\nabstract class MyBaseMessageHandler implements MessageHandlerInterface, LoggableOutputInterface\n{\n    use LoggableOutputTrait;\n}\n\n#[LoggableOutput(filename: 'my_log_name')]\nclass MyMessageHandler extends MyBaseMessageHandler\n{\n    public function __invoke(MyMessage $myMessage): void\n    {\n        // ...\n    }\n}\n```\n\n### Doctrine annotations\n\nIf you're using a version of PHP prior to 8,\n[Doctrine annotations](https://www.doctrine-project.org/projects/annotations.html) can be used instead of PHP attributes\nas a way to override the default configuration.\n\n1. Require the Doctrine annotations library with Composer:\n\n    ```sh\n    composer require doctrine/annotations\n    ```\n\n1. Enable annotations support in the configuration:\n\n    ```yaml\n    bizkit_loggable_command:\n        file_handler_options:\n            enable_annotations: true\n    ```\n\nThe `LoggableOutput` PHP attribute also serves as the Doctrine annotation class.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\Command\\LoggableCommand;\nuse Bizkit\\LoggableCommandBundle\\ConfigurationProvider\\Attribute\\LoggableOutput;\n\n/**\n * @LoggableOutput(filename=\"my_custom_name\", type=\"rotating_file\")\n */\nclass MyLoggableCommand extends LoggableCommand\n{\n    protected function execute(InputInterface $input, OutputInterface $output): int\n    {\n        // ...\n    }\n}\n```\n\nAnnotation options are also inherited from all parent classes.\n\n### Adding other Monolog handlers to the output logger\n\nTo add other Monolog handlers to the output logger, in case of an inclusive channel list, add the Monolog channel\ndefined with the `channel_name` option to their `channels` list.\n\n```yaml\nmonolog:\n    handlers:\n        sentry:\n            type: sentry\n            dsn: '%sentry_dsn%'\n            channels: [ \"loggable_output\" ]\n```\n\nIn case of an exclusive channel list, [disable the auto-exclusion](#disabling-auto-exclusion) feature for that handler.\n\n\u003e **NOTE:** In case of multiple output loggers, each output logger will use the same handler instance.\n\n### Monolog channel auto-exclusion\n\nThe Monolog channel used by the bundle is automatically excluded from all other Monolog handlers with an exclusive\nchannel list. There's no need to manually add the channel to the list.\n\n```yaml\nmonolog:\n    handlers:\n        main:\n            # ...\n            channels: [ \"!event\" ] # the bundle's channel is excluded automatically, no need to add it manually\n```\n\n#### Disabling auto-exclusion\n\nIf you don't want the channel to be automatically excluded from a certain handler, add it to the `channels` list\nprefixed with `!!`.\n\n```yaml\nmonolog:\n    handlers:\n        main:\n            # ...\n            channels: [ \"!event\", \"!!loggable_output\" ] # this will prevent the channel from being auto-excluded\n```\n\n## Handler factories\n\nHandler factories are used to instantiate \u0026 configure the file handler used by the output logger.\n\n### Custom handler factories\n\nTo implement a custom handler factory all you need to do is create a service which implements\nthe `HandlerFactoryInterface` interface.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\HandlerFactory\\HandlerFactoryInterface;\n\nclass CustomHandlerFactory implements HandlerFactoryInterface\n{\n    public function __invoke(array $handlerOptions): HandlerInterface\n    {\n        // configure \u0026 return a monolog handler\n    }\n}\n```\n\nUse the FQCN of the service in the configuration:\n\n```yaml\nbizkit_loggable_command:\n    file_handler_options:\n        type: App\\CustomHandlerFactory\n```\n\nIf you are not using\nSymfony's [autoconfigure](https://symfony.com/doc/4.4/service_container.html#the-autoconfigure-option) feature or wish\nto use an alias in the configuration, tag the service with the `bizkit_loggable_command.handler_factory` tag.\n\n```yaml\nApp\\CustomHandlerFactory:\n    # Prevents the handler factory from being tagged twice,\n    # once by the autoconfigure feature \u0026 once manually\n    autoconfigure: false\n    tags:\n        - { name: bizkit_loggable_command.handler_factory, type: custom }\n\nbizkit_loggable_command:\n    file_handler_options:\n        type: custom\n```\n\nTo simplify the configuring of a handler factory the bundle comes with an `AbstractHandlerFactory` class which can be\nused to configure some common handler features such as the [PSR 3](https://www.php-fig.org/psr/psr-3/) log message\nprocessor or a log formatter.\n\n```php\nnamespace App;\n\nuse Bizkit\\LoggableCommandBundle\\HandlerFactory\\AbstractHandlerFactory;\nuse Monolog\\Handler\\HandlerInterface;\n\nclass CustomHandlerFactory extends AbstractHandlerFactory\n{\n    protected function getHandler(array $handlerOptions): HandlerInterface\n    {\n        // return a monolog handler\n    }\n}\n```\n\n## Versioning\n\nThis project adheres to [Semantic Versioning 2.0.0](http://semver.org/).\n\n## Reporting issues\n\nUse the [issue tracker](https://github.com/HypeMC/loggable-command-bundle/issues) to report any issues you might have.\n\n## License\n\nSee the [LICENSE](LICENSE) file for license rights and limitations (MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypemc%2Floggable-command-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhypemc%2Floggable-command-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypemc%2Floggable-command-bundle/lists"}