package common import ( "encoding/json" "strings" "fiskerinc.com/modules/logger" "github.com/go-playground/validator/v10" "github.com/pkg/errors" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/bsontype" "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" ) type TRexConfigResponse struct { CANBus CANBus `json:"canbus"` LogLevel LogLevel `json:"log_level" validate:"oneof=0 1 2 3 4 5"` Log *LogConfig `json:"log,omitempty" bson:"log,omitempty"` DebugMask string `json:"debug_mask,omitempty" bson:"debug_mask,omitempty"` DLTEnabled bool `json:"dlt_enabled,omitempty" bson:"dlt_enabled,omitempty"` DLTLevel int `json:"dlt_level,omitempty" bson:"dlt_level,omitempty" validate:"oneof=0 1 2 3 4 5 6 255"` IDPSEnabled bool `json:"idps_enabled,omitempty" bson:"idps_enabled,omitempty"` } /* The given values for memory and disk buffer min's and max's DFT_TMTRC_BUF_SZ = “16MiB”; MAX_TMTRC_BUF_SZ = “1GiB”; DFT_TMTRC_DISKQ_SZ = “1GiB”; MAX_TMTRC_DISKQ_SZ = “16GiB”; */ type CANBus struct { Enabled bool `json:"enabled" bson:"enabled"` DataLogger bool `json:"data_logger_enabled" bson:"data_logger"` MemBuffSize int `json:"max_mem_buffer_size,omitempty" bson:"mem_buff_size" validate:"min=0,max=1073741824"` DiskBuffSize int `json:"max_disk_buffer_size,omitempty" bson:"disk_buff_size" validate:"min=0,max=17179869184"` Filters []CANFilter `json:"filters,omitempty" bson:"filters,omitempty"` DTCEnabled *bool `json:"dtc_enabled" bson:"dtc_enabled"` } type LogLevel int type LogConfig struct { Matches []LogConfigChannel `json:"matches,omitempty" bson:"matches,omitempty"` } type LogConfigChannel struct { Channel string `json:"channel,omitempty" bson:"channel,omitempty"` Level LogLevel `json:"level" bson:"level" validate:"oneof=0 1 2 3 4 5"` } func CANBusStructLevelValidation(sl validator.StructLevel) { canBus := sl.Current().Interface().(CANBus) // If we want this canbus to be enabled, then we should enforce the size, otherwise let it be if canBus.Enabled { if canBus.MemBuffSize < 16777216 { sl.ReportError(canBus.MemBuffSize, "max_mem_buffer_size", "MemBuffSize", "canbussizeEnabled", "") } if canBus.DiskBuffSize < 1073741824 { sl.ReportError(canBus.DiskBuffSize, "max_disk_buffer_size", "DiskBuffSize", "canbussizeEnabled", "") } } } const ( ChannelCMD = "cmd" ) const ( Trace LogLevel = iota Debug Info Warn Error Critical ) const ( TraceLabel = "trace" DebugLabel = "debug" InfoLabel = "info" WarnLabel = "warning" ErrorLabel = "error" CriticalLabel = "critical" ) var logLevels = [...]string{TraceLabel, DebugLabel, InfoLabel, WarnLabel, ErrorLabel, CriticalLabel} func (l LogLevel) String() string { return logLevels[l] } // Turn a string into a log level, if we fail, we return trace as default level func UnmarshalLogLevelString(level string) (l LogLevel) { level = strings.ToLower(level) switch level { case TraceLabel: l = Trace case DebugLabel: l = Debug case InfoLabel: l = Info case WarnLabel: l = Warn case ErrorLabel: l = Error case CriticalLabel: l = Critical default: l = Trace } return l } func (l LogLevel) MarshalJSON() ([]byte, error) { return json.Marshal(logLevels[l]) } func (l *LogLevel) UnmarshalJSON(data []byte) error { var level string err := json.Unmarshal(data, &level) if err != nil { return errors.WithStack(err) } switch level { case TraceLabel: *l = Trace case DebugLabel: *l = Debug case InfoLabel: *l = Info case WarnLabel: *l = Warn case ErrorLabel: *l = Error case CriticalLabel: *l = Critical default: return ErrInvalidLogLevel } return nil } func (l LogLevel) MarshalBSONValue() (bsontype.Type, []byte, error) { return bson.MarshalValue(logLevels[l]) } func (l *LogLevel) UnmarshalBSONValue(t bsontype.Type, value []byte) error { if t != bsontype.String { return errors.Errorf("invalid bson value type '%s'", t.String()) } level, _, ok := bsoncore.ReadString(value) if !ok { return errors.New("invalid bson string value") } switch level { case TraceLabel: *l = Trace case DebugLabel: *l = Debug case InfoLabel: *l = Info case ErrorLabel: *l = Error case WarnLabel: *l = Warn case CriticalLabel: *l = Critical default: return ErrInvalidLogLevel } return nil } var ErrInvalidLogLevel = errors.New("invalid log level") // Converts trex log level to the logger level, so its easy to log // WithLevel() uses a different iota order compared to our LogLevel func (l LogLevel) ToLoggerLevel() func() *logger.Event { switch l { case Trace: return logger.Trace case Debug: return logger.Debug case Info: return logger.Info case Warn: return logger.Warn case Error: return logger.Error case Critical: return logger.Error default: return logger.Warn } }