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.
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
}
}
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
}
}
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"
}
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"
}
Name | Github |
---|---|
Ayaka Neko | @nekomeowww |
MIT.