logger.go 2.94 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
package helpers
//
// GangGo Application Server
// Copyright (C) 2017 Lukas Matt <lukas@zauberstuhl.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

import (
  "fmt"
  "github.com/revel/revel"
zauberstuhl's avatar
zauberstuhl committed
23
  federation "git.feneas.org/ganggo/federation"
24 25
  "github.com/revel/log15"
  "github.com/getsentry/raven-go"
zauberstuhl's avatar
zauberstuhl committed
26
  "errors"
27 28 29 30 31 32
)

type AppLogWrapper struct {
  Name string
}

33 34 35 36 37
// SentryLogHandler will intercept logging and send all errors
// with a log level greater then info to the specified DSN
type SentryLogHandler struct {}

func (handler SentryLogHandler) Log(record *log15.Record) error {
zauberstuhl's avatar
zauberstuhl committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
  if record.Lvl == log15.LvlError || record.Lvl == log15.LvlCrit {
    var errs []error
    // search for errors in the logger context
    for _, ctx := range record.Ctx {
      if err, ok := ctx.(error); ok {
        errs = append(errs, err)
      }
    }

    if len(errs) == 0 {
      // there was an error/crit event but no error type
      // was found lets create one and send it to sentry
      var errMsg string
      for _, ctx := range record.Ctx {
        if msg, ok := ctx.(string); ok {
          errMsg = errMsg + " " + msg
        }
      }
      errs = append(errs, errors.New(errMsg))
    }
58

zauberstuhl's avatar
zauberstuhl committed
59 60
    // send asynchronously to the sentry endpoint
    for _, err := range errs {
61 62 63 64 65 66
      raven.CaptureError(err, nil)
    }
  }
  return revel.GetRootLogHandler().Log(record)
}

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
func (wrap AppLogWrapper) Println(v ...interface{}) { wrap.Print(v) }

func (wrap AppLogWrapper) Print(v ...interface{}) {
  if len(v) <= 0 {
    return
  }

  if wrap.Name == "gorm" {
    logType := v[0].(string)
    if logType == "log" && len(v) > 2 {
      path := v[1].(string)
      revel.AppLog.Error(path, "error", v[2])
      return
    } else if logType == "sql" && len(v) > 5 {
      path := v[1].(string)
      revel.AppLog.Debug(path, "time", v[2],
        "query", v[3], "params", v[4], "rows", v[5])
      return
    }
  } else if wrap.Name == "federation" {
zauberstuhl's avatar
zauberstuhl committed
87 88 89 90 91 92 93 94
    var logType string
    switch log := v[0].(type) {
    case []interface{}:
      logType = log[0].(string)
    case interface{}:
      logType = log.(string)
    }

95 96 97 98 99 100 101
    if logType == federation.LOG_C_RED {
      revel.AppLog.Error(fmt.Sprintf("%+v", v))
    } else if logType == federation.LOG_C_YELLOW {
      revel.AppLog.Warn(fmt.Sprintf("%+v", v))
    } else {
      revel.AppLog.Debug(fmt.Sprintf("%+v", v))
    }
zauberstuhl's avatar
zauberstuhl committed
102
    return
103 104 105
  }
  revel.AppLog.Debug(fmt.Sprintf("%+v", v))
}