Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Matveev committed Jun 14, 2023
0 parents commit ddb397e
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.idea
/example/
34 changes: 34 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import "flag"

type NginxConfig struct {
LogFile string
Config string
ConfigFile string
TimeFormat string
}

type SentryConfig struct {
Debug bool
Dsn string
Env string
Message string
ServerName string
}

var nginxConfig NginxConfig
var sentryConfig SentryConfig

func init() {
flag.StringVar(&nginxConfig.LogFile, "file", "/var/log/nginx/access.log", "Nginx access log to follow.")
flag.StringVar(&nginxConfig.ConfigFile, "config-file", "/var/log/nginx/access.log", "Nginx access log to follow.")
flag.StringVar(&nginxConfig.Config, "config", "", "Nginx config contents instead of `config-file`.")
flag.StringVar(&nginxConfig.TimeFormat, "time-format", "02/Jan/2006:15:04:05 -0700", "Nginx log time format.")

flag.BoolVar(&sentryConfig.Debug, "debug", false, "Debug Sentry.")
flag.StringVar(&sentryConfig.Dsn, "dsn", "", "Sentry DSN. If not specified, get from SENTRY_DNS env (recommended).")
flag.StringVar(&sentryConfig.Env, "env", "", "Environment to use in event.")
flag.StringVar(&sentryConfig.Message, "message", "500", "Issue message.")
flag.StringVar(&sentryConfig.ServerName, "server-name", "", "Server name to use in event, default to current host name.")
}
19 changes: 19 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module github.com/AlexanderMatveev/sentry-nginx

go 1.20

require (
github.com/getsentry/sentry-go v0.21.0
github.com/hpcloud/tail v1.0.0
github.com/papertrail/go-tail v0.0.0-20221103124010-5087eb6a0a07
github.com/satyrius/gonx v1.4.0
)

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/smartystreets/goconvey v1.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)
32 changes: 32 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/getsentry/sentry-go v0.21.0 h1:c9l5F1nPF30JIppulk4veau90PK6Smu3abgVtVQWon4=
github.com/getsentry/sentry-go v0.21.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/papertrail/go-tail v0.0.0-20221103124010-5087eb6a0a07 h1:LT8DNsrcjaqaKy/I2HTGjxRFazKu48G3AXoIXklcquw=
github.com/papertrail/go-tail v0.0.0-20221103124010-5087eb6a0a07/go.mod h1:aUf8RteFEultHEEQ5zPUnFIs/hLoI2z8vJHmn0rcuEk=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/satyrius/gonx v1.4.0 h1:F3uxif5Yx6FBzdQAh79bHQK6CTJugOcN0w0Z8azQuQg=
github.com/satyrius/gonx v1.4.0/go.mod h1:+r8KNe5d2tjkZU+DfhERo0G6KxkGih+1qYF6tqLHwvk=
github.com/smartystreets/assertions v1.13.1 h1:Ef7KhSmjZcK6AVf9YbJdvPYG9avaF0ZxudX+ThRdWfU=
github.com/smartystreets/goconvey v1.8.0 h1:Oi49ha/2MURE0WexF052Z0m+BNSGirfjg5RL+JXWq3w=
github.com/smartystreets/goconvey v1.8.0/go.mod h1:EdX8jtrTIj26jmjCOVNMVSIYAtgexqXKHOXW2Dx9JLg=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
123 changes: 123 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package main

import (
"flag"
"github.com/getsentry/sentry-go"
"github.com/hpcloud/tail"
"github.com/satyrius/gonx"
"io"
"log"
"os"
"strings"
"time"
)

func main() {
flag.Parse()
if sentryConfig.Dsn == "" {
sentryConfig.Dsn = os.Getenv("SENTRY_DSN")
}
if sentryConfig.ServerName == "" {
var err error
if sentryConfig.ServerName, err = os.Hostname(); err != nil {
log.Fatalf("can't get hostname from OS: %v", err)
}
}

if err := sentry.Init(sentry.ClientOptions{
Dsn: sentryConfig.Dsn,
TracesSampleRate: 1.0,
EnableTracing: true,
Debug: sentryConfig.Debug,
}); err != nil {
log.Fatalf("sentry.Init: %s", err)
}
defer sentry.Flush(2 * time.Second)

log.Printf("server name: %s", sentryConfig.ServerName)
log.Printf("env: %s", sentryConfig.Env)
log.Printf("debug: %v", sentryConfig.Debug)
log.Printf("file: %v", nginxConfig.LogFile)
log.Printf("time format: %v", nginxConfig.TimeFormat)

t, err := tail.TailFile(nginxConfig.LogFile, tail.Config{
Location: &tail.SeekInfo{
Whence: 2,
},
Follow: true,
MustExist: false,
ReOpen: true,
})
if err != nil {
log.Fatalf("tail.TailFile error: %v", err)
}

var cr io.Reader
if nginxConfig.Config != "" {
cr = strings.NewReader(nginxConfig.Config)
} else {
if cr, err = os.Open(nginxConfig.ConfigFile); err != nil {
log.Fatalf("error opening config file: %v", err)
}
}

parser, err := gonx.NewNginxParser(cr, "main")
if err != nil {
log.Fatalf("gonx.NewNginxParser error: %v", err)
}

for line := range t.Lines {
if line.Text == "" {
continue
}
entry, err := parser.ParseString(line.Text)
if err != nil {
log.Fatalf("parser.ParseString error: %v", err)
}
status, err := entry.IntField("status")
if err != nil {
log.Fatalf("entry.IntField(status) error: %v", err)
}
if status != 500 {
continue
}
timeLocalString, err := entry.Field("time_local")
if err != nil {
log.Fatalf("entry.IntField(time_local) error: %v", err)
}
timeLocal, err := time.Parse(nginxConfig.TimeFormat, timeLocalString)
event := &sentry.Event{
Message: sentryConfig.Message,
Level: sentry.LevelFatal,
Timestamp: timeLocal,
Environment: sentryConfig.Env,
ServerName: sentryConfig.ServerName,
Request: &sentry.Request{
Headers: map[string]string{},
},
}
if referer := entry.Fields()["http_referer"]; referer != "" {
event.Request.Headers["Referer"] = referer
}
if userAgent := entry.Fields()["http_user_agent"]; userAgent != "" {
event.Request.Headers["User-Agent"] = userAgent
}
if uri := entry.Fields()["request_uri"]; uri != "" {
event.Request.URL = uri
}
if method := entry.Fields()["request_method"]; method != "" {
event.Request.Method = method
}
if ip := entry.Fields()["remote_addr"]; ip != "" {
event.User.IPAddress = ip
}
if xff := entry.Fields()["http_x_forwarded_for"]; xff != "" {
event.Request.Headers["X-Forwarded-For"] = xff
}
sentry.CaptureEvent(event)
}

if err := t.Wait(); err != nil {
log.Fatalf("t.Wait error: %v", err)
}
}

0 comments on commit ddb397e

Please sign in to comment.