# Log Me - logging library for Laravel projects

`Log Me` is a library that sends your log messages to Elasticsearch. It ships with sensible default configuration.

No more files, MySQL tables etc. - log everything to Elasticsearch, unbound by log message structure and search / filter messages as you see fit.


# Table of contents

1. [Installation](#installation)
2. [Configuration](#configuration)
3. [Writing log messages](#writing-log-messages)
4. [Usage with Monolog](#use-with-monolog)
5. [Using in your project](#using-in-your-project)
6. [Reading log messages](#reading-log-messages)
7. [Running tests](#running-tests)


## Installation

`composer require buckhill/logme`

## Configuration

When installed, a file `logme.php` will be published to your `config/` directory (`config/logme.php`).


Options:

```php
<?php

return [
    // Array of hosts of your Elasticsearch cluster
    'hosts'     => [env('ELASTICSEARCH_URL', 'localhost:9200')],

    // Number of connection retries
    'retries'   => env('ELASTICSEARCH_RETRIES', 1),

    // Local logging. This is used to debug problems with Elasticsearch connection.
    // Disabled by default, enable if you need to debug issues with Elasticsearch
    'log'       => [
        'enabled' => false,
        'filename' => 'elasticsearch.log'
    ]
];

```


## Writing log messages

There's a single function that's used to write messages:

```php

function logme(string $message, string $channel, string $index, [int $log_level, [array $context = []]])

```


1. `$message` - text of the message you want to save. Not JSON, regular text such as `You have been logged out`
2. `$channel` - the channel (arbitrary name), so you can filter messages based on that value. Example: `404 errors`, `broker-{id}`, `debug` etc. It's a label meaningful for your project.
3. `$index` - Elasticsearch index (index = database). Used so that logs can be grouped into units they belong to. If there's a multitenant app, you want to distinguish who the messages relate to. That's what index is for.
4. `$log_level` - PSR-3 log level (check Monolog). If not set, the level will always be INFO (int: 200)
5. `$context` - context is an array with extra info you might want to save to the log, like user agent info, IP addresses, message parameters

If you want to record user activity, you'd call the function like this:

```php
<?php

$id = 1; // Our fictional user id

logme('You logged in successfully', 'authentication', "user-$id");
```

The 2nd parameter (`'authentication'`) is a channel, or an arbitrary string that relates to your application and use case when you search for the logs.

3rd parameter is an Elasticserach index. In this case, it's dynamic index, so you don't have to create an index before adding data to Elasticsearch.
Think of index as a database. In the above example, you'd find all messages related to a user defined by `$id` by reading from index called `user-$id`


## Usage with Monolog

Writing Monolog logs to ElasticSearch using `Log Me` is trivial - this library ships with Monolog ElasticSearch handler.
You can find the class at `Service/ElasticHandler`.


How to add the handler to your Monolog logger:

```php
<?php

$logger = new Logger($channel);

// Create the handler
$handler = new ElasticHandler();

// Set the index and type (this is mandatory)
$handler->setIndex($index)->setType($channel);

// Add the handler to Logger instance. Your logs are now written to ElasticSearch
$logger->pushHandler($handler);
```


## Using in your project

Calling a simple function for every type of message or log can quickly become unmaintainable.
We suggest you create smaller functions to write different **types** of messages to the index wrapped around `logme` function.

Let's say you want to write debug messages to ElasticSearch. Maintainable and clear way woudld be to create a function that you call and pass the debug message to it.

```php
<?php

function debugmsg($message, $extra = [])
{
    // ElasticSearch Type and Index are hardcoded into the function.
    // Instead of remembering parameter order, you can pass only 2 parameters to your debug function
    return logme($message, 'debugmsg', 'debug', null, $extra);
}

// Save a debug message to ES with HTTP request headers (if you use Laravel)
debugmsg('This is controller action test', ['headers' => request()->headers()]);
```

## Reading log messages

-- to be written --


## Running tests

Tests are written using `phpunit`. Clone the repository, open your CLI, navigate to the library directory and type `phpunit`.
