mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
232 lines
7.2 KiB
Go
232 lines
7.2 KiB
Go
package datadog
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
const (
|
|
ArithmeticProcessorType = "arithmetic-processor"
|
|
AttributeRemapperType = "attribute-remapper"
|
|
CategoryProcessorType = "category-processor"
|
|
DateRemapperType = "date-remapper"
|
|
GeoIPParserType = "geo-ip-parser"
|
|
GrokParserType = "grok-parser"
|
|
MessageRemapperType = "message-remapper"
|
|
NestedPipelineType = "pipeline"
|
|
ServiceRemapperType = "service-remapper"
|
|
StatusRemapperType = "status-remapper"
|
|
StringBuilderProcessorType = "string-builder-processor"
|
|
TraceIdRemapperType = "trace-id-remapper"
|
|
UrlParserType = "url-parser"
|
|
UserAgentParserType = "user-agent-parser"
|
|
)
|
|
|
|
// LogsProcessor struct represents the processor object from Config API.
|
|
type LogsProcessor struct {
|
|
Name *string `json:"name"`
|
|
IsEnabled *bool `json:"is_enabled"`
|
|
Type *string `json:"type"`
|
|
Definition interface{} `json:"definition"`
|
|
}
|
|
|
|
// ArithmeticProcessor struct represents unique part of arithmetic processor
|
|
// object from config API.
|
|
type ArithmeticProcessor struct {
|
|
Expression *string `json:"expression"`
|
|
Target *string `json:"target"`
|
|
IsReplaceMissing *bool `json:"is_replace_missing"`
|
|
}
|
|
|
|
// AttributeRemapper struct represents unique part of attribute remapper object
|
|
// from config API.
|
|
type AttributeRemapper struct {
|
|
Sources []string `json:"sources"`
|
|
SourceType *string `json:"source_type"`
|
|
Target *string `json:"target"`
|
|
TargetType *string `json:"target_type"`
|
|
PreserveSource *bool `json:"preserve_source"`
|
|
OverrideOnConflict *bool `json:"override_on_conflict"`
|
|
}
|
|
|
|
// CategoryProcessor struct represents unique part of category processor object
|
|
// from config API.
|
|
type CategoryProcessor struct {
|
|
Target *string `json:"target"`
|
|
Categories []Category `json:"categories"`
|
|
}
|
|
|
|
// Category represents category object from config API.
|
|
type Category struct {
|
|
Name *string `json:"name"`
|
|
Filter *FilterConfiguration `json:"filter"`
|
|
}
|
|
|
|
// SourceRemapper represents the object from config API that contains
|
|
// only a list of sources.
|
|
type SourceRemapper struct {
|
|
Sources []string `json:"sources"`
|
|
}
|
|
|
|
// GeoIPParser represents geoIpParser object from config API.
|
|
type GeoIPParser struct {
|
|
Sources []string `json:"sources"`
|
|
Target *string `json:"target"`
|
|
}
|
|
|
|
type StringBuilderProcessor struct {
|
|
Template *string `json:"template"`
|
|
Target *string `json:"target"`
|
|
IsReplaceMissing *bool `json:"is_replace_missing"`
|
|
}
|
|
|
|
// GrokParser represents the grok parser processor object from config API.
|
|
type GrokParser struct {
|
|
Source *string `json:"source"`
|
|
Samples []string `json:"samples"`
|
|
GrokRule *GrokRule `json:"grok"`
|
|
}
|
|
|
|
// GrokRule represents the rules for grok parser from config API.
|
|
type GrokRule struct {
|
|
SupportRules *string `json:"support_rules"`
|
|
MatchRules *string `json:"match_rules"`
|
|
}
|
|
|
|
// NestedPipeline represents the pipeline as processor from config API.
|
|
type NestedPipeline struct {
|
|
Filter *FilterConfiguration `json:"filter"`
|
|
Processors []LogsProcessor `json:"processors,omitempty"`
|
|
}
|
|
|
|
// UrlParser represents the url parser from config API.
|
|
type UrlParser struct {
|
|
Sources []string `json:"sources"`
|
|
Target *string `json:"target"`
|
|
NormalizeEndingSlashes *bool `json:"normalize_ending_slashes"`
|
|
}
|
|
|
|
// UserAgentParser represents the user agent parser from config API.
|
|
type UserAgentParser struct {
|
|
Sources []string `json:"sources"`
|
|
Target *string `json:"target"`
|
|
IsEncoded *bool `json:"is_encoded"`
|
|
}
|
|
|
|
// buildProcessor converts processor Definition of type interface{} to a map of string and interface{}.
|
|
// Simple cast from interface{} to map[string]interface{} will not work for our case here,
|
|
// since the underlying types of Definition are the processor structs.
|
|
func buildProcessor(definition interface{}) (map[string]interface{}, error) {
|
|
inrec, err := json.Marshal(definition)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var processor map[string]interface{}
|
|
if err = json.Unmarshal(inrec, &processor); err != nil {
|
|
return nil, err
|
|
}
|
|
return processor, err
|
|
}
|
|
|
|
// MarshalJSON serializes logsprocessor struct to config API compatible json object.
|
|
func (processor *LogsProcessor) MarshalJSON() ([]byte, error) {
|
|
mapProcessor, err := buildProcessor(processor.Definition)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
mapProcessor["name"] = processor.Name
|
|
mapProcessor["is_enabled"] = processor.IsEnabled
|
|
mapProcessor["type"] = processor.Type
|
|
jsn, err := json.Marshal(mapProcessor)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return jsn, err
|
|
}
|
|
|
|
// UnmarshalJSON deserializes the config API json object to LogsProcessor struct.
|
|
func (processor *LogsProcessor) UnmarshalJSON(data []byte) error {
|
|
var processorHandler struct {
|
|
Type *string `json:"type"`
|
|
Name *string `json:"name"`
|
|
IsEnabled *bool `json:"is_enabled"`
|
|
}
|
|
if err := json.Unmarshal(data, &processorHandler); err != nil {
|
|
return err
|
|
}
|
|
|
|
processor.Name = processorHandler.Name
|
|
processor.IsEnabled = processorHandler.IsEnabled
|
|
processor.Type = processorHandler.Type
|
|
|
|
switch *processorHandler.Type {
|
|
case ArithmeticProcessorType:
|
|
var arithmeticProcessor ArithmeticProcessor
|
|
if err := json.Unmarshal(data, &arithmeticProcessor); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = arithmeticProcessor
|
|
case AttributeRemapperType:
|
|
var attributeRemapper AttributeRemapper
|
|
if err := json.Unmarshal(data, &attributeRemapper); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = attributeRemapper
|
|
case CategoryProcessorType:
|
|
var categoryProcessor CategoryProcessor
|
|
if err := json.Unmarshal(data, &categoryProcessor); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = categoryProcessor
|
|
case DateRemapperType,
|
|
MessageRemapperType,
|
|
ServiceRemapperType,
|
|
StatusRemapperType,
|
|
TraceIdRemapperType:
|
|
var sourceRemapper SourceRemapper
|
|
if err := json.Unmarshal(data, &sourceRemapper); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = sourceRemapper
|
|
case GeoIPParserType:
|
|
var geoIPParser GeoIPParser
|
|
if err := json.Unmarshal(data, &geoIPParser); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = geoIPParser
|
|
case GrokParserType:
|
|
var grokParser GrokParser
|
|
if err := json.Unmarshal(data, &grokParser); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = grokParser
|
|
case NestedPipelineType:
|
|
var nestedPipeline NestedPipeline
|
|
if err := json.Unmarshal(data, &nestedPipeline); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = nestedPipeline
|
|
case StringBuilderProcessorType:
|
|
var stringBuilder StringBuilderProcessor
|
|
if err := json.Unmarshal(data, &stringBuilder); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = stringBuilder
|
|
case UrlParserType:
|
|
var urlParser UrlParser
|
|
if err := json.Unmarshal(data, &urlParser); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = urlParser
|
|
case UserAgentParserType:
|
|
var userAgentParser UserAgentParser
|
|
if err := json.Unmarshal(data, &userAgentParser); err != nil {
|
|
return err
|
|
}
|
|
processor.Definition = userAgentParser
|
|
default:
|
|
return fmt.Errorf("cannot unmarshal processor of type: %s", *processorHandler.Type)
|
|
}
|
|
return nil
|
|
}
|