# Io Logger

This module adds logging functionality to IO applications.

## Installation

`composer require apexl/io-logger`

## Usage

```
    logger()->debug('This is a debug message for the 'default' log stream);
    
    logger('error')->warning('This is a warning message for the 'error' log stream);
    
    logger('import')->info('This is an info message for the 'import' log stream);
```

The `logger()` function is available globally. It takes a single argument `string $stream` defines the stream to send
the message to. If the stream does not exist, it will default to the `default` stream.  `logger()` returns a PSR-3
compliant `LoggerInterface` object. and accepts the following log levels:

- `debug`
- `info`
- `notice`
- `warning`
- `error`
- `critical`
- `alert`
- `emergency`

## Configuration

This module reuqires a block in your `config.json` file keyed with `logger:`

```php
  "logger": {
    "level": "debug",
    "streams": {
      "default": {
        "handlers": [
          {
            "destination": "file"
          }
        ]
        ...
      },
    }
  },

```

`logger (object)`:  The top-level `logger` key is an object that contains the following keys:

`logger.catchErrors (bool)`: If `true`, the logger will log PHP errors and exceptions to the `error` stream. Default is
`true`.

`logger.level (string)`:  A [PSR-3](https://www.php-fig.org/psr/psr-3/) log level. Default is `debug`. The top-level
`level` key sets the default log level for all streams. Individual streams can override this setting.

`logger.streams (object)`:  An object that contains one or more stream definitions. Each stream definition is keyed by a
unique name. The default stream is named `default`.

`logger.streams.[name].level (string)`: A PSR-3 log level. Sets the level for this stream. If not set, it will default
to the top-level `logger.level` setting.

`logger.streams.[name].handlers (array)`:  An array of handlers. Handlers define where log messages are sent. See the
Handlers section below for more information.

## Handlers

Handlers define where log messages are sent. The `destination` key is required for all handlers. Currently the following
destinations are supported:

Handlers can can also have a `level (string)` key that sets the minimum log level for this handler. If not set, it will
default to the stream's log level.

- `file`: Writes the log message to a file.
    - `file (string)`: The path to the log file. If the file does not exist, it will be created.
    - `maxFiles (int)`: The maximum number of daily log files to keep. Default is 7.


- `error_log`: Writes the log message to the PHP error log.


- `logstash`: Writes the log message to a Logstash server.
    - `host (string)`: The hostname of the Logstash server. default `localhost`
    - `port (int)`: The port number of the Logstash server. default `5000`
    - `application (string)`: The name of the application. Nullable
    - `system (string)`: The name of the system. Nullable


- `mail`: Emails the log messages, using the application mailer (`smtp.*` config).
  Records are buffered and sent as a single email when the process ends, so a run
  producing many records sends one email rather than one per record. A send failure
  is written to the PHP error log and never propagates.
    - `to (string)`: The recipient address. Without one the handler does nothing.
    - `subject (string)`: The email subject. Defaults to `<stream> log: <level> and above`.
    - `max_records (int)`: How many records to buffer. Default `0` (unlimited); beyond a
      positive limit the oldest records are dropped.

## Development

Internally this module uses the [Monolog](https://github.com/Seldaek/monolog) library. To create additional handlers:

- Add the handler to the `apexl\Io\modules\logger\enums\Handler` enum.
- Modify `apexl\Io\modules\logge\services\logger::handler()` method to create the handler object. This method recieves
  the handler block from `config.json`, and should return a `Monolog\Handler\HandlerInterface` object.

## Todo

- Refactor instanciation of handlers to allow other modules to add custom handlers.