diff --git a/plugins/parsers/csv/parser.go b/plugins/parsers/csv/parser.go index 2bbf2ce0df858..4a86a33de2e30 100644 --- a/plugins/parsers/csv/parser.go +++ b/plugins/parsers/csv/parser.go @@ -33,18 +33,10 @@ func (p *Parser) compile(r *bytes.Reader) (*csv.Reader, error) { // ensures that the reader reads records of different lengths without an error csvReader.FieldsPerRecord = -1 if p.Delimiter != "" { - runeStr := []rune(p.Delimiter) - if len(runeStr) > 1 { - return nil, fmt.Errorf("delimiter must be a single character, got: %s", p.Delimiter) - } - csvReader.Comma = runeStr[0] + csvReader.Comma = []rune(p.Delimiter)[0] } if p.Comment != "" { - runeStr := []rune(p.Comment) - if len(runeStr) > 1 { - return nil, fmt.Errorf("comment must be a single character, got: %s", p.Comment) - } - csvReader.Comment = runeStr[0] + csvReader.Comment = []rune(p.Comment)[0] } return csvReader, nil } @@ -71,7 +63,9 @@ func (p *Parser) Parse(buf []byte) ([]telegraf.Metric, error) { //concatenate header names for i := range header { name := header[i] - name = strings.Trim(name, " ") + if p.TrimSpace { + name = strings.Trim(name, " ") + } if len(headerNames) <= i { headerNames = append(headerNames, name) } else { @@ -80,14 +74,11 @@ func (p *Parser) Parse(buf []byte) ([]telegraf.Metric, error) { } } p.ColumnNames = headerNames[p.SkipColumns:] - } else if len(p.ColumnNames) > 0 { + } else { // if columns are named, just skip header rows for i := 0; i < p.HeaderRowCount; i++ { csvReader.Read() } - } else if p.HeaderRowCount == 0 && len(p.ColumnNames) == 0 { - // if there is no header and no DataColumns, that's an error - return nil, fmt.Errorf("there must be a header if `csv_data_columns` is not specified") } table, err := csvReader.ReadAll() @@ -140,7 +131,9 @@ func (p *Parser) parseRecord(record []string) (telegraf.Metric, error) { for i, fieldName := range p.ColumnNames { if i < len(record) { value := record[i] - value = strings.Trim(value, " ") + if p.TrimSpace { + value = strings.Trim(value, " ") + } // attempt type conversions if iValue, err := strconv.ParseInt(value, 10, 64); err == nil { recordFields[fieldName] = iValue @@ -162,14 +155,14 @@ func (p *Parser) parseRecord(record []string) (telegraf.Metric, error) { // will default to plugin name measurementName := p.MetricName if recordFields[p.MeasurementColumn] != nil { - measurementName = recordFields[p.MeasurementColumn].(string) + measurementName = fmt.Sprintf("%v", recordFields[p.MeasurementColumn]) } for _, tagName := range p.TagColumns { if recordFields[tagName] == nil { return nil, fmt.Errorf("could not find field: %v", tagName) } - tags[tagName] = recordFields[tagName].(string) + tags[tagName] = fmt.Sprintf("%v", recordFields[tagName]) delete(recordFields, tagName) } @@ -178,7 +171,7 @@ func (p *Parser) parseRecord(record []string) (telegraf.Metric, error) { if recordFields[p.TimestampColumn] == nil { return nil, fmt.Errorf("timestamp column: %v could not be found", p.TimestampColumn) } - tStr := recordFields[p.TimestampColumn].(string) + tStr := fmt.Sprintf("%v", recordFields[p.TimestampColumn]) if p.TimestampFormat == "" { return nil, fmt.Errorf("timestamp format must be specified") } diff --git a/plugins/parsers/registry.go b/plugins/parsers/registry.go index eb1269da81532..32027e417a878 100644 --- a/plugins/parsers/registry.go +++ b/plugins/parsers/registry.go @@ -211,6 +211,28 @@ func newCSVParser(metricName string, timestampColumn string, timestampFormat string, defaultTags map[string]string) (Parser, error) { + + if header == 0 && len(dataColumns) == 0 { + // if there is no header and no DataColumns, that's an error + return nil, fmt.Errorf("there must be a header if `csv_data_columns` is not specified") + } + + if delimiter != "" { + runeStr := []rune(delimiter) + if len(runeStr) > 1 { + return nil, fmt.Errorf("delimiter must be a single character, got: %s", delimiter) + } + delimiter = fmt.Sprintf("%v", runeStr[0]) + } + + if comment != "" { + runeStr := []rune(comment) + if len(runeStr) > 1 { + return nil, fmt.Errorf("delimiter must be a single character, got: %s", comment) + } + comment = fmt.Sprintf("%v", runeStr[0]) + } + parser := &csv.Parser{ MetricName: metricName, HeaderRowCount: header,