github.com/avenga/couper@v1.12.2/logging/hooks/custom_logs.go (about) 1 package hooks 2 3 import ( 4 "github.com/hashicorp/hcl/v2" 5 "github.com/sirupsen/logrus" 6 "github.com/zclconf/go-cty/cty" 7 8 "github.com/avenga/couper/config/env" 9 "github.com/avenga/couper/config/request" 10 "github.com/avenga/couper/eval" 11 "github.com/avenga/couper/internal/seetie" 12 "github.com/avenga/couper/logging" 13 ) 14 15 var ( 16 _ logrus.Hook = &CustomLogs{} 17 18 acTypeField string 19 beTypeField string 20 ) 21 22 const customLogField = "custom" 23 24 type CustomLogs struct{} 25 26 func init() { 27 logConf := *logging.DefaultConfig 28 logConf.TypeFieldKey = "couper_access" 29 env.DecodeWithPrefix(&logConf, "ACCESS_") 30 acTypeField = logConf.TypeFieldKey 31 32 logConf = *logging.DefaultConfig 33 logConf.TypeFieldKey = "couper_backend" 34 env.DecodeWithPrefix(&logConf, "BACKEND_") 35 beTypeField = logConf.TypeFieldKey 36 } 37 38 func (c *CustomLogs) Levels() []logrus.Level { 39 return []logrus.Level{ 40 logrus.PanicLevel, // reasonable? 41 logrus.FatalLevel, // reasonable? 42 logrus.ErrorLevel, 43 logrus.WarnLevel, // not used? 44 logrus.InfoLevel, 45 } 46 } 47 48 func (c *CustomLogs) Fire(entry *logrus.Entry) error { 49 if entry.Context != nil { 50 if t, exists := entry.Data["type"]; exists { 51 switch t { 52 case "couper_job": 53 fallthrough 54 case acTypeField: 55 fireAccess(entry) 56 case beTypeField: 57 fireUpstream(entry) 58 } 59 } 60 } 61 62 return nil 63 } 64 65 func fireAccess(entry *logrus.Entry) { 66 evalCtx, ok := entry.Context.Value(request.ContextType).(*eval.Context) 67 if !ok { 68 return 69 } 70 71 bodies := entry.Context.Value(request.LogCustomAccess) 72 if bodies == nil { 73 return 74 } 75 76 hclBodies, ok := bodies.([]hcl.Body) 77 if !ok { 78 return 79 } 80 81 if fields := eval.ApplyCustomLogs(evalCtx.HCLContextSync(), hclBodies, entry); len(fields) > 0 { 82 entry.Data[customLogField] = fields 83 } 84 } 85 86 func fireUpstream(entry *logrus.Entry) { 87 logError, _ := entry.Context.Value(request.LogCustomUpstreamError).(*error) 88 if *logError != nil { 89 entry.Debug(*logError) 90 return 91 } 92 logValue, _ := entry.Context.Value(request.LogCustomUpstreamValue).(*cty.Value) 93 fields := seetie.ValueToLogFields(*logValue) 94 entry.Data[customLogField] = fields 95 }