Skip to content

Latest commit

 

History

History
198 lines (151 loc) · 5.07 KB

README.md

File metadata and controls

198 lines (151 loc) · 5.07 KB

Logstash hook for logrus :walrus:

Go Report Status

Use this hook to send the logs to Logstash.

Improved with better callframe override abilities and better support for elasticsearch index patterns by merging additional fields into key=val format and store them into fields field in elasticsearch document.

Usage

Logstash configuration

Send to Elasticsearch Cluster

input {
    tcp {
        port => 8911 # Select a free and opening port
        codec => json
        tcp_keep_alive => true # optional: keep the connection alive
    }
}

output {
    elasticsearch {
        hosts => ["https://localhost:9200"]
        ssl => true
        cacert => "" # optional: path to elasticsearch host CA certificates, such as /etc/logstash/certs/ca.crt
        api_key => "" # Kibana generated API key, if you dont have API key configurated, use username and password instead
        index => "" # optional: Specify the index you wish to send to
    }
}

Directly print in console

input {
    tcp {
        port => 8911 # Select a free and opening port
        codec => json
        tcp_keep_alive => true # optional: keep the connection alive
    }
}

output {
    stdout {
        codec => rubydebug
    }
}

Golang code references

General usage

package main

import (
        "net"

        "github.com/sirupsen/logrus"
        logrustash "github.com/nekomeowww/logrus-logstash-hook"
)

func main() {
        // new logrus instance
        logger := logrus.New()

        // these fields will be at the top-level fields of documents
        predefinedFields := logrus.Fields{"type": "myappName"}

        // create a hook to send logs to Logstash
        hook, err := logrustash.New("tcp", "logstash.mycompany.net:8911", logrustash.DefaultFormatter(predefinedFields))
        if err != nil {
                log.Fatal(err)
        }

        // add this hook to the logger
        logger.Hooks.Add(hook)

        // this package will merge the non-pre-defined fields into key=val format,
        // and store them into fields field of the document for better elasticsearch compatibility,
        // may also reduce the time to deal with the elasticsearch index template
        laterAddedFields := logrus.Fields{"exampleFields", "fields"}

        // then just use as normal logrus
        logger.WithFields(laterAddedFields).Info("Hello World!")
}

This is how it will look like:

{
    "@timestamp" => "2016-02-29T16:57:23.000Z",
      "@version" => "1",
         "level" => "info",
       "message" => "Hello World!",
        "fields" => "exampleFields=fields", # merged fields
          "host" => "172.17.0.1",
          "port" => 45199,
          "type" => "myappName"
}

With caller information

package main

import (
        "net"
        "runtime"

        "github.com/sirupsen/logrus"
        logrustash "github.com/nekomeowww/logrus-logstash-hook"


)

var Log *logrus.Logger

func setCaller(entry *logrus.Entry) {
        // get the caller context
        pc, file, line, _ := runtime.Caller(1)

        // transform pc pointer to *runtime.Func
        funcDetail := runtime.FuncForPC(pc)
        var funcName string
        if funcDetail != nil {
                // get the function name
                funcName = funcDetail.Name()
        }

        // set the caller context into entry.Context
        entry.Context = context.WithValue(context.Background(), logrustash.ContextKeyRuntimeCaller, &runtime.Frame{
                File:     file,
                Line:     line,
                Function: funcName,
        })
}

func Info(args ...interface{}) {
        entry := logrus.NewEntry(Log)
        setCaller(entry, 1)
        entry.Info(args...)
}

func main() {
        // new logrus instance
        Log = logrus.New()
        // set ReportCaller to true to get the callframe
        Log.SetReportCaller(true)

        // these fields will be at the top-level fields of documents
        predefinedFields := logrus.Fields{"type": "myappName"}

        // create a hook to send logs to Logstash
        hook, err := logrustash.New("tcp", "logstash.mycompany.net:8911", logrustash.DefaultFormatter(predefinedFields))
        if err != nil {
                log.Fatal(err)
        }

        // add this hook to the logger
        Log.Hooks.Add(hook)

        // then just use as normal logrus
        Info("Hello World!")
}
{
    "@timestamp" => 2022-07-15T09:22:34Z,
      "@version" => "1",
          "file" => "<path/to/code>:1",
      "function" => "main",
         "level" => "info",
       "message" => "Hello World",
          "type" => "log"
}

Original Creator

Boaz Shuster

Maintainers

Name Github
Ayaka Neko @nekomeowww

License

MIT.