# LORA Logger

This package contains both the customised handler for saving the logs into a elasticsearch database, and a factory for creating customised loggers that can use that handler.

The customised handler will forward the logs to an existing logging service through our own celery service. This logging service will handle the logs and input them into the database. This is done to unionise the logs into a single database.

## Diagram

```mermaid
flowchart LR

    services["Services\n<small>All backend projects\nthat need the logging\nsystem</small>"]-->producer[[Producer]]
    subgraph "LoraLogger package"
    producer-->queue[Queue]
    end
    queue-->consumer[[Consumer]]
    subgraph "AskLora logger service"
    consumer-->database[(<small>ElasticSearch\nDatabase</small>)]
    end

```

## How to use

Currently, this package exports a logging handler. Loggers with this handler will be automatically send the records to the elasticsearch server set using the environment variable.

### Package installation

there are two ways to install this pacakge

- install the package locally. first, build the project:
  ```bash
  poetry build
  ```
  then you can install using pip
  ```bash
  pip install /path/to/logger/dist/loralogger-0.3.0-py3-none-any.whl
  ```
  or if youre using poetry, use:
  ```bash
  poetry add /path/to/logger/dist/loralogger-0.3.0-py3-none-any.tar.gz
  ```
- Install the package from pip
  ```bash
  pip install loralogger
  ```

### Using this package

First, set these environment variables:

```
# Set amqp backend
AMQP_BROKER=localhost
AMQP_PORT=5672
AMQP_USER=rabbitmq
AMQP_PASSWORD=rabbitmq

# set results backend
REDIS_HOST=localhost
REDIS_PORT=6379

# set sentinel mode
REDIS_SENTINEL=False  # or True
```

Then you can use the logger in two ways:

1. Use dedicated logger instances for specific projects. These will be automatically log to Elasticsearch (i.e. using the ESHandler)

   - import the from loralogger logger factory

   ```python
   from loralogger import LoggerInstances, LoraLogger
   ```

   - get the logger instance with the `LoggerInstances` enum as label (preferred), or you can also use other labels by passing a string

     ```python
     askloraxalpaca_logger = LoraLogger.get_logger(
        LoggerInstances.ASKLORAXALPACA,
        log_to_console=True,
     )
     ```

   - Use the logger instance
     ```python
     askloraxalpaca_logger.info("This works!")
     ```

2. Use the handler directly to your own logger instance:

   - import the handler

     ```python
     from loralogger import LogToESHandler
     ```

   - initialise logging instance

     ```python
     import logging 
     backend_logger = logging.getLogger("backend")
     ```

   - Create the handler instance, initialise with the desired LoggerInstances

     ```python
     logger_instance = LoggerInstances.LEDGER
     handler = LogToESHandler(logger_instance)
     ```

   - add the handler instance to the logger

     ```python
     backend_logger.addHandler(handler)
     ```

   - And finally, use the logger

     ```python
     backend_logger.info("This is an info")
     ```

# Features

- Send your logs to Elasticsearch by setting `send_to_es` argument to `True` when initialising your logger, i.e.
  ```python
  logger = LoraLogger.getLogger("backend", log_to_es=True)
  ```
- Normally, sending logs to Elasticsearch will use RabbitMQ to not block the running operation, but you can skip it and send the logs directly using Elasticsearch API by setting `skip_queue` argument to `True`:
  ```python
  logger = LoraLogger.get_logger(
    'ledger',
    log_to_es=True,
    skip_queue=True,
  )
  ```
- You can use `event` and `id` to categorise your logs further in Elasticsearch:
  ```python
  logger.info('Job started', event='calling-api', id='job-1)
  ```

# Notes

- if the pip installation fails, check this link https://github.com/celery/librabbitmq/issues/131#issuecomment-661884151
