local_vendor/github.com/aliyun/aliyun-log-go-sdk/log_config.go (398 lines of code) (raw):

package sls import ( "encoding/json" "errors" ) // const InputTypes const ( InputTypeSyslog = "syslog" InputTypeStreamlog = "streamlog" InputTypePlugin = "plugin" InputTypeFile = "file" ) // const LogFileTypes const ( LogFileTypeApsaraLog = "apsara_log" LogFileTypeRegexLog = "common_reg_log" LogFileTypeJSONLog = "json_log" LogFileTypeDelimiterLog = "delimiter_log" ) // const OutputType const ( OutputTypeLogService = "LogService" ) // const MergeType const ( MergeTypeTopic = "topic" MergeTypeLogstore = "logstore" ) const ( TopicFormatNone = "none" // no topic TopicFormatMachineGroup = "group_topic" // machine group's topic // otherwise, file path regex. // eg, file path /var/log/nginx/access.log, TopicFormat: /var/log/([^/]+)/access\.log, so topic is 'nginx' ) var NoConfigFieldError = errors.New("no this config field") var InvalidTypeError = errors.New("invalid config type") // IsValidInputType check if specific inputType is valid func IsValidInputType(inputType string) bool { switch inputType { case InputTypeSyslog, InputTypeStreamlog, InputTypePlugin, InputTypeFile: return true } return false } // InputDetail defines log_config input // @note : deprecated and no maintenance type InputDetail struct { LogType string `json:"logType"` LogPath string `json:"logPath"` FilePattern string `json:"filePattern"` LocalStorage bool `json:"localStorage"` TimeKey string `json:"timeKey"` TimeFormat string `json:"timeFormat"` LogBeginRegex string `json:"logBeginRegex"` Regex string `json:"regex"` Keys []string `json:"key"` FilterKeys []string `json:"filterKey"` FilterRegex []string `json:"filterRegex"` TopicFormat string `json:"topicFormat"` Separator string `json:"separator"` AutoExtend bool `json:"autoExtend"` } func ConvertToInputDetail(detail InputDetailInterface) (*InputDetail, bool) { // ConvertToPluginLogConfigInputDetail need a plugin if mapVal, ok := detail.(map[string]interface{}); ok { if logType, ok := mapVal["logType"]; !ok || logType != "common_reg_log" { return nil, false } } else { return nil, false } buf, err := json.Marshal(detail) if err != nil { return nil, false } destDetail := &InputDetail{} err = json.Unmarshal(buf, destDetail) return destDetail, err == nil } type SensitiveKey struct { Key string `json:"key"` Type string `json:"type"` RegexBegin string `json:"regex_begin"` RegexContent string `json:"regex_content"` All bool `json:"all"` ConstString string `json:"const"` } // ApsaraLogConfigInputDetail apsara log config type ApsaraLogConfigInputDetail struct { LocalFileConfigInputDetail LogBeginRegex string `json:"logBeginRegex"` } // InitApsaraLogConfigInputDetail ... func InitApsaraLogConfigInputDetail(detail *ApsaraLogConfigInputDetail) { InitLocalFileConfigInputDetail(&detail.LocalFileConfigInputDetail) detail.LogBeginRegex = ".*" detail.LogType = LogFileTypeApsaraLog } func AddNecessaryApsaraLogInputConfigField(inputConfigDetail map[string]interface{}) { if _, ok := inputConfigDetail["logBeginRegex"]; !ok { inputConfigDetail["logBeginRegex"] = ".*" } } func ConvertToApsaraLogConfigInputDetail(detail InputDetailInterface) (*ApsaraLogConfigInputDetail, bool) { // ConvertToPluginLogConfigInputDetail need a plugin if mapVal, ok := detail.(map[string]interface{}); ok { if logType, ok := mapVal["logType"]; !ok || logType != "apsara_log" { return nil, false } } else { return nil, false } buf, err := json.Marshal(detail) if err != nil { return nil, false } destDetail := &ApsaraLogConfigInputDetail{} err = json.Unmarshal(buf, destDetail) return destDetail, err == nil } // RegexConfigInputDetail regex log config type RegexConfigInputDetail struct { LocalFileConfigInputDetail Key []string `json:"key"` LogBeginRegex string `json:"logBeginRegex"` Regex string `json:"regex"` } // InitRegexConfigInputDetail ... func InitRegexConfigInputDetail(detail *RegexConfigInputDetail) { InitLocalFileConfigInputDetail(&detail.LocalFileConfigInputDetail) detail.LogBeginRegex = ".*" detail.Regex = "(.*)" detail.LogType = LogFileTypeRegexLog } func AddNecessaryRegexLogInputConfigField(inputConfigDetail map[string]interface{}) { if _, ok := inputConfigDetail["logBeginRegex"]; !ok { inputConfigDetail["logBeginRegex"] = ".*" } if _, ok := inputConfigDetail["regex"]; !ok { inputConfigDetail["regex"] = "(.*)" } if _, ok := inputConfigDetail["key"]; !ok { inputConfigDetail["key"] = []string{"content"} } } func ConvertToRegexConfigInputDetail(detail InputDetailInterface) (*RegexConfigInputDetail, bool) { // ConvertToPluginLogConfigInputDetail need a plugin if mapVal, ok := detail.(map[string]interface{}); ok { if logType, ok := mapVal["logType"]; !ok || logType != "common_reg_log" { return nil, false } } else { return nil, false } buf, err := json.Marshal(detail) if err != nil { return nil, false } destDetail := &RegexConfigInputDetail{} err = json.Unmarshal(buf, destDetail) return destDetail, err == nil } // JSONConfigInputDetail pure json log config type JSONConfigInputDetail struct { LocalFileConfigInputDetail TimeKey string `json:"timeKey"` } // InitJSONConfigInputDetail ... func InitJSONConfigInputDetail(detail *JSONConfigInputDetail) { InitLocalFileConfigInputDetail(&detail.LocalFileConfigInputDetail) detail.LogType = LogFileTypeJSONLog } func AddNecessaryJSONLogInputConfigField(inputConfigDetail map[string]interface{}) { if _, ok := inputConfigDetail["timeKey"]; !ok { inputConfigDetail["timeKey"] = "" } } func ConvertToJSONConfigInputDetail(detail InputDetailInterface) (*JSONConfigInputDetail, bool) { // ConvertToPluginLogConfigInputDetail need a plugin if mapVal, ok := detail.(map[string]interface{}); ok { if logType, ok := mapVal["logType"]; !ok || logType != "json_log" { return nil, false } } else { return nil, false } buf, err := json.Marshal(detail) if err != nil { return nil, false } destDetail := &JSONConfigInputDetail{} err = json.Unmarshal(buf, destDetail) return destDetail, err == nil } // DelimiterConfigInputDetail delimiter log config type DelimiterConfigInputDetail struct { LocalFileConfigInputDetail Separator string `json:"separator"` Quote string `json:"quote"` Key []string `json:"key"` TimeKey string `json:"timeKey"` AutoExtend bool `json:"autoExtend"` } // InitDelimiterConfigInputDetail ... func InitDelimiterConfigInputDetail(detail *DelimiterConfigInputDetail) { InitLocalFileConfigInputDetail(&detail.LocalFileConfigInputDetail) detail.Quote = "\u0001" detail.AutoExtend = true detail.LogType = LogFileTypeDelimiterLog } func AddNecessaryDelimiterLogInputConfigField(inputConfigDetail map[string]interface{}) { if _, ok := inputConfigDetail["quote"]; !ok { inputConfigDetail["quote"] = "\u0001" } if _, ok := inputConfigDetail["autoExtend"]; !ok { inputConfigDetail["autoExtend"] = true } if _, ok := inputConfigDetail["timeKey"]; !ok { inputConfigDetail["timeKey"] = "" } } func ConvertToDelimiterConfigInputDetail(detail InputDetailInterface) (*DelimiterConfigInputDetail, bool) { // ConvertToPluginLogConfigInputDetail need a plugin if mapVal, ok := detail.(map[string]interface{}); ok { if logType, ok := mapVal["logType"]; !ok || logType != "delimiter_log" { return nil, false } } else { return nil, false } buf, err := json.Marshal(detail) if err != nil { return nil, false } destDetail := &DelimiterConfigInputDetail{} err = json.Unmarshal(buf, destDetail) return destDetail, err == nil } // LocalFileConfigInputDetail all file input detail's basic config type LocalFileConfigInputDetail struct { CommonConfigInputDetail LogType string `json:"logType"` LogPath string `json:"logPath"` FilePattern string `json:"filePattern"` TimeFormat string `json:"timeFormat"` TopicFormat string `json:"topicFormat,omitempty"` Preserve bool `json:"preserve"` PreserveDepth int `json:"preserveDepth"` FileEncoding string `json:"fileEncoding,omitempty"` DiscardUnmatch bool `json:"discardUnmatch"` MaxDepth int `json:"maxDepth"` TailExisted bool `json:"tailExisted"` DiscardNonUtf8 bool `json:"discardNonUtf8"` DelaySkipBytes int `json:"delaySkipBytes"` IsDockerFile bool `json:"dockerFile"` DockerIncludeLabel map[string]string `json:"dockerIncludeLabel,omitempty"` DockerExcludeLabel map[string]string `json:"dockerExcludeLabel,omitempty"` DockerIncludeEnv map[string]string `json:"dockerIncludeEnv,omitempty"` DockerExcludeEnv map[string]string `json:"dockerExcludeEnv,omitempty"` } func GetFileConfigInputDetailType(detail InputDetailInterface) (string, bool) { // ConvertToPluginLogConfigInputDetail need a plugin if mapVal, ok := detail.(map[string]interface{}); ok { if logType, ok := mapVal["logType"]; ok { return logType.(string), true } } return "", false } // InitLocalFileConfigInputDetail ... func InitLocalFileConfigInputDetail(detail *LocalFileConfigInputDetail) { InitCommonConfigInputDetail(&detail.CommonConfigInputDetail) detail.FileEncoding = "utf8" detail.MaxDepth = 100 detail.TopicFormat = TopicFormatNone detail.Preserve = true detail.DiscardUnmatch = true } func AddNecessaryLocalFileInputConfigField(inputConfigDetail map[string]interface{}) { if _, ok := inputConfigDetail["fileEncoding"]; !ok { inputConfigDetail["fileEncoding"] = "utf8" } if _, ok := inputConfigDetail["maxDepth"]; !ok { inputConfigDetail["maxDepth"] = 100 } if _, ok := inputConfigDetail["topicFormat"]; !ok { inputConfigDetail["topicFormat"] = TopicFormatNone } if _, ok := inputConfigDetail["preserve"]; !ok { inputConfigDetail["preserve"] = true } if _, ok := inputConfigDetail["discardUnmatch"]; !ok { inputConfigDetail["discardUnmatch"] = true } if _, ok := inputConfigDetail["timeFormat"]; !ok { inputConfigDetail["timeFormat"] = "" } } // PluginLogConfigInputDetail plugin log config, eg: docker stdout, binlog, mysql, http... type PluginLogConfigInputDetail struct { CommonConfigInputDetail PluginDetail LogConfigPluginInput `json:"plugin"` } // InitPluginLogConfigInputDetail ... func InitPluginLogConfigInputDetail(detail *PluginLogConfigInputDetail) { InitCommonConfigInputDetail(&detail.CommonConfigInputDetail) } func ConvertToPluginLogConfigInputDetail(detail InputDetailInterface) (*PluginLogConfigInputDetail, bool) { // ConvertToPluginLogConfigInputDetail need a plugin if mapVal, ok := detail.(map[string]interface{}); ok { if _, ok := mapVal["plugin"]; !ok { return nil, false } if _, ok := mapVal["logType"]; ok { return nil, false } buf, err := json.Marshal(detail) if err != nil { return nil, false } destDetail := &PluginLogConfigInputDetail{} err = json.Unmarshal(buf, destDetail) return destDetail, err == nil } return nil, false } // StreamLogConfigInputDetail syslog config type StreamLogConfigInputDetail struct { CommonConfigInputDetail Tag string `json:"tag"` } // InitStreamLogConfigInputDetail ... func InitStreamLogConfigInputDetail(detail *StreamLogConfigInputDetail) { InitCommonConfigInputDetail(&detail.CommonConfigInputDetail) } func ConvertToStreamLogConfigInputDetail(detail InputDetailInterface) (*StreamLogConfigInputDetail, bool) { // ConvertToStreamLogConfigInputDetail need a tag if mapVal, ok := detail.(map[string]interface{}); ok { if _, ok := mapVal["tag"]; !ok { return nil, false } } else { return nil, false } buf, err := json.Marshal(detail) if err != nil { return nil, false } destDetail := &StreamLogConfigInputDetail{} err = json.Unmarshal(buf, destDetail) return destDetail, err == nil } // CommonConfigInputDetail is all input detail's basic config type CommonConfigInputDetail struct { LocalStorage bool `json:"localStorage"` FilterKeys []string `json:"filterKey,omitempty"` FilterRegex []string `json:"filterRegex,omitempty"` ShardHashKey []string `json:"shardHashKey,omitempty"` EnableTag bool `json:"enableTag"` EnableRawLog bool `json:"enableRawLog"` MaxSendRate int `json:"maxSendRate"` SendRateExpire int `json:"sendRateExpire"` SensitiveKeys []SensitiveKey `json:"sensitive_keys,omitempty"` MergeType string `json:"mergeType,omitempty"` DelayAlarmBytes int `json:"delayAlarmBytes,omitempty"` AdjustTimeZone bool `json:"adjustTimezone"` LogTimeZone string `json:"logTimezone,omitempty"` Priority int `json:"priority,omitempty"` } // InitCommonConfigInputDetail ... func InitCommonConfigInputDetail(detail *CommonConfigInputDetail) { detail.LocalStorage = true detail.EnableTag = true detail.MaxSendRate = -1 detail.MergeType = MergeTypeTopic } // AddNecessaryInputConfigField ... func AddNecessaryInputConfigField(inputConfigDetail map[string]interface{}) { if _, ok := inputConfigDetail["localStorage"]; !ok { inputConfigDetail["localStorage"] = true } if _, ok := inputConfigDetail["enableTag"]; !ok { inputConfigDetail["enableTag"] = true } if _, ok := inputConfigDetail["maxSendRate"]; !ok { inputConfigDetail["maxSendRate"] = -1 } if _, ok := inputConfigDetail["mergeType"]; !ok { inputConfigDetail["mergeType"] = MergeTypeTopic } if logTypeInterface, ok := inputConfigDetail["logType"]; ok { if logType, ok := logTypeInterface.(string); ok { AddNecessaryLocalFileInputConfigField(inputConfigDetail) switch logType { case LogFileTypeApsaraLog: AddNecessaryApsaraLogInputConfigField(inputConfigDetail) case LogFileTypeRegexLog: AddNecessaryRegexLogInputConfigField(inputConfigDetail) case LogFileTypeJSONLog: AddNecessaryJSONLogInputConfigField(inputConfigDetail) case LogFileTypeDelimiterLog: AddNecessaryDelimiterLogInputConfigField(inputConfigDetail) } } } } // UpdateInputConfigField ... func UpdateInputConfigField(detail InputDetailInterface, key string, val interface{}) error { if mapVal, ok := detail.(map[string]interface{}); ok { if _, ok := mapVal[key]; !ok { return NoConfigFieldError } mapVal[key] = val return nil } return InvalidTypeError } // OutputDetail defines output type OutputDetail struct { ProjectName string `json:"projectName"` LogStoreName string `json:"logstoreName"` } // InputDetailInterface all input detail's interface type InputDetailInterface interface { } // LogConfig defines log config type LogConfig struct { Name string `json:"configName"` LogSample string `json:"logSample"` InputType string `json:"inputType"` // syslog plugin file InputDetail InputDetailInterface `json:"inputDetail"` OutputType string `json:"outputType"` OutputDetail OutputDetail `json:"outputDetail"` CreateTime uint32 `json:"createTime,omitempty` LastModifyTime uint32 `json:"lastModifyTime,omitempty"` }