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  }