Compare commits
12 Commits
ga-azure-m
...
1.6.0-rc4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71948a8f84 | ||
|
|
b5babc3f00 | ||
|
|
5f0fbc7d30 | ||
|
|
cde9c37e26 | ||
|
|
83c560af22 | ||
|
|
38075d8ff8 | ||
|
|
3c039921e1 | ||
|
|
0ffa24c4b3 | ||
|
|
1734e97d58 | ||
|
|
6332ede542 | ||
|
|
2a9198cea6 | ||
|
|
1e95f9785c |
@@ -105,6 +105,8 @@
|
||||
- [#3648](https://github.com/influxdata/telegraf/issues/3648): Fix InfluxDB output not able to reconnect when server address changes.
|
||||
- [#3957](https://github.com/influxdata/telegraf/issues/3957): Fix parsing of dos line endings in the smart input.
|
||||
- [#3754](https://github.com/influxdata/telegraf/issues/3754): Fix precision truncation when no timestamp included.
|
||||
- [#3655](https://github.com/influxdata/telegraf/issues/3655): Fix SNMPv3 connection with Cisco ASA 5515 in snmp input.
|
||||
- [#3981](https://github.com/influxdata/telegraf/pull/3981): Export all vars defined in /etc/default/telegraf.
|
||||
|
||||
## v1.5.3 [2018-03-14]
|
||||
|
||||
|
||||
2
Godeps
2
Godeps
@@ -70,7 +70,7 @@ github.com/shirou/gopsutil fc04d2dd9a512906a2604242b35275179e250eda
|
||||
github.com/shirou/w32 3c9377fc6748f222729a8270fe2775d149a249ad
|
||||
github.com/Shopify/sarama 3b1b38866a79f06deddf0487d5c27ba0697ccd65
|
||||
github.com/Sirupsen/logrus 61e43dc76f7ee59a82bdf3d71033dc12bea4c77d
|
||||
github.com/soniah/gosnmp 5ad50dc75ab389f8a1c9f8a67d3a1cd85f67ed15
|
||||
github.com/soniah/gosnmp f15472a4cd6f6ea7929e4c7d9f163c49f059924f
|
||||
github.com/StackExchange/wmi f3e2bae1e0cb5aef83e319133eabfee30013a4a5
|
||||
github.com/streadway/amqp 63795daa9a446c920826655f26ba31c81c860fd6
|
||||
github.com/stretchr/objx facf9a85c22f48d2f52f2380e4efce1768749a89
|
||||
|
||||
@@ -397,9 +397,7 @@ CROSS APPLY (
|
||||
OPTION( RECOMPILE );
|
||||
`
|
||||
|
||||
const sqlPerformanceCountersV2 string = `DECLARE @DynamicPerf NVARCHAR(MAX) = ''
|
||||
|
||||
SET @DynamicPerf += REPLACE('
|
||||
const sqlPerformanceCountersV2 string = `
|
||||
DECLARE @PCounters TABLE
|
||||
(
|
||||
object_name nvarchar(128),
|
||||
@@ -409,140 +407,120 @@ DECLARE @PCounters TABLE
|
||||
cntr_type INT,
|
||||
Primary Key(object_name, counter_name, instance_name)
|
||||
);
|
||||
|
||||
INSERT INTO @PCounters
|
||||
SELECT DISTINCT
|
||||
RTrim(spi.object_name) object_name,
|
||||
RTrim(spi.counter_name) counter_name,
|
||||
RTrim(spi.instance_name) instance_name,
|
||||
spi.cntr_value,
|
||||
CAST(spi.cntr_value AS BIGINT) AS cntr_value,
|
||||
spi.cntr_type
|
||||
FROM sys.dm_os_performance_counters AS spi
|
||||
WHERE (
|
||||
counter_name IN (
|
||||
"SQL Compilations/sec",
|
||||
"SQL Re-Compilations/sec",
|
||||
"User Connections",
|
||||
"Batch Requests/sec",
|
||||
"Logouts/sec",
|
||||
"Logins/sec",
|
||||
"Processes blocked",
|
||||
"Latch Waits/sec",
|
||||
"Full Scans/sec",
|
||||
"Index Searches/sec",
|
||||
"Page Splits/sec",
|
||||
"Page Lookups/sec",
|
||||
"Page Reads/sec",
|
||||
"Page Writes/sec",
|
||||
"Readahead Pages/sec",
|
||||
"Lazy Writes/sec",
|
||||
"Checkpoint Pages/sec",
|
||||
"Page life expectancy",
|
||||
"Log File(s) Size (KB)",
|
||||
"Log File(s) Used Size (KB)",
|
||||
"Data File(s) Size (KB)",
|
||||
"Transactions/sec",
|
||||
"Write Transactions/sec",
|
||||
"Active Temp Tables",
|
||||
"Temp Tables Creation Rate",
|
||||
"Temp Tables For Destruction",
|
||||
"Free Space in tempdb (KB)",
|
||||
"Version Store Size (KB)",
|
||||
"Memory Grants Pending",
|
||||
"Free list stalls/sec",
|
||||
"Buffer cache hit ratio",
|
||||
"Buffer cache hit ratio base",
|
||||
"Backup/Restore Throughput/sec",
|
||||
"Total Server Memory (KB)",
|
||||
"Target Server Memory (KB)"
|
||||
'SQL Compilations/sec',
|
||||
'SQL Re-Compilations/sec',
|
||||
'User Connections',
|
||||
'Batch Requests/sec',
|
||||
'Logouts/sec',
|
||||
'Logins/sec',
|
||||
'Processes blocked',
|
||||
'Latch Waits/sec',
|
||||
'Full Scans/sec',
|
||||
'Index Searches/sec',
|
||||
'Page Splits/sec',
|
||||
'Page Lookups/sec',
|
||||
'Page Reads/sec',
|
||||
'Page Writes/sec',
|
||||
'Readahead Pages/sec',
|
||||
'Lazy Writes/sec',
|
||||
'Checkpoint Pages/sec',
|
||||
'Page life expectancy',
|
||||
'Log File(s) Size (KB)',
|
||||
'Log File(s) Used Size (KB)',
|
||||
'Data File(s) Size (KB)',
|
||||
'Transactions/sec',
|
||||
'Write Transactions/sec',
|
||||
'Active Temp Tables',
|
||||
'Temp Tables Creation Rate',
|
||||
'Temp Tables For Destruction',
|
||||
'Free Space in tempdb (KB)',
|
||||
'Version Store Size (KB)',
|
||||
'Memory Grants Pending',
|
||||
'Free list stalls/sec',
|
||||
'Buffer cache hit ratio',
|
||||
'Buffer cache hit ratio base',
|
||||
'Backup/Restore Throughput/sec',
|
||||
'Total Server Memory (KB)',
|
||||
'Target Server Memory (KB)'
|
||||
)
|
||||
) OR (
|
||||
instance_name IN ("_Total","Column store object pool")
|
||||
instance_name IN ('_Total','Column store object pool')
|
||||
AND counter_name IN (
|
||||
"Log Flushes/sec",
|
||||
"Log Flush Wait Time",
|
||||
"Lock Timeouts/sec",
|
||||
"Number of Deadlocks/sec",
|
||||
"Lock Waits/sec",
|
||||
"Latch Waits/sec",
|
||||
"Memory broker clerk size",
|
||||
"Log Bytes Flushed/sec",
|
||||
"Bytes Sent to Replica/sec",
|
||||
"Log Send Queue",
|
||||
"Bytes Sent to Transport/sec",
|
||||
"Sends to Replica/sec",
|
||||
"Bytes Sent to Transport/sec",
|
||||
"Sends to Transport/sec",
|
||||
"Bytes Received from Replica/sec",
|
||||
"Receives from Replica/sec",
|
||||
"Flow Control Time (ms/sec)",
|
||||
"Flow Control/sec",
|
||||
"Resent Messages/sec",
|
||||
"Redone Bytes/sec",
|
||||
"XTP Memory Used (KB)"
|
||||
'Log Flushes/sec',
|
||||
'Log Flush Wait Time',
|
||||
'Lock Timeouts/sec',
|
||||
'Number of Deadlocks/sec',
|
||||
'Lock Waits/sec',
|
||||
'Latch Waits/sec',
|
||||
'Memory broker clerk size',
|
||||
'Log Bytes Flushed/sec',
|
||||
'Bytes Sent to Replica/sec',
|
||||
'Log Send Queue',
|
||||
'Bytes Sent to Transport/sec',
|
||||
'Sends to Replica/sec',
|
||||
'Bytes Sent to Transport/sec',
|
||||
'Sends to Transport/sec',
|
||||
'Bytes Received from Replica/sec',
|
||||
'Receives from Replica/sec',
|
||||
'Flow Control Time (ms/sec)',
|
||||
'Flow Control/sec',
|
||||
'Resent Messages/sec',
|
||||
'Redone Bytes/sec',
|
||||
'XTP Memory Used (KB)'
|
||||
) OR (
|
||||
counter_name IN (
|
||||
"Log Bytes Received/sec",
|
||||
"Log Apply Pending Queue",
|
||||
"Redone Bytes/sec",
|
||||
"Recovery Queue",
|
||||
"Log Apply Ready Queue"
|
||||
'Log Bytes Received/sec',
|
||||
'Log Apply Pending Queue',
|
||||
'Redone Bytes/sec',
|
||||
'Recovery Queue',
|
||||
'Log Apply Ready Queue'
|
||||
)
|
||||
AND instance_name = "_Total"
|
||||
AND instance_name = '_Total'
|
||||
)
|
||||
) OR (
|
||||
counter_name IN ("Transaction Delay")
|
||||
counter_name IN ('Transaction Delay')
|
||||
) OR (
|
||||
counter_name IN (
|
||||
"CPU usage %",
|
||||
"CPU usage % base",
|
||||
"Queued requests",
|
||||
"Requests completed/sec",
|
||||
"Blocked tasks"
|
||||
'CPU usage %',
|
||||
'CPU usage % base',
|
||||
'Queued requests',
|
||||
'Requests completed/sec',
|
||||
'Blocked tasks'
|
||||
)
|
||||
) OR (
|
||||
counter_name IN (
|
||||
"Active memory grant amount (KB)",
|
||||
"Disk Read Bytes/sec",
|
||||
"Disk Read IO Throttled/sec",
|
||||
"Disk Read IO/sec",
|
||||
"Disk Write Bytes/sec",
|
||||
"Disk Write IO Throttled/sec",
|
||||
"Disk Write IO/sec",
|
||||
"Used memory (KB)"
|
||||
'Active memory grant amount (KB)',
|
||||
'Disk Read Bytes/sec',
|
||||
'Disk Read IO Throttled/sec',
|
||||
'Disk Read IO/sec',
|
||||
'Disk Write Bytes/sec',
|
||||
'Disk Write IO Throttled/sec',
|
||||
'Disk Write IO/sec',
|
||||
'Used memory (KB)'
|
||||
)
|
||||
) OR (
|
||||
object_name LIKE "%User Settable%"
|
||||
OR object_name LIKE "%SQL Errors%"
|
||||
object_name LIKE '%User Settable%'
|
||||
OR object_name LIKE '%SQL Errors%'
|
||||
)
|
||||
'
|
||||
,'"','''')
|
||||
|
||||
SET @DynamicPerf += REPLACE('
|
||||
SELECT "sqlserver_performance" AS [measurement],
|
||||
REPLACE(@@SERVERNAME,"\",":") AS [sql_instance],
|
||||
pc.object_name AS [object],
|
||||
pc.counter_name AS [counter],
|
||||
CASE pc.instance_name WHEN "_Total" THEN "Total" ELSE ISNULL(pc.instance_name,"") END AS [instance],
|
||||
CASE WHEN pc.cntr_type = 537003264 AND pc1.cntr_value > 0 THEN (pc.cntr_value * 1.0) / (pc1.cntr_value * 1.0) * 100 ELSE pc.cntr_value END AS [value]
|
||||
FROM @PCounters AS pc
|
||||
LEFT OUTER JOIN @PCounters AS pc1
|
||||
ON (
|
||||
pc.counter_name = REPLACE(pc1.counter_name," base","")
|
||||
OR pc.counter_name = REPLACE(pc1.counter_name," base"," (ms)")
|
||||
)
|
||||
AND pc.object_name = pc1.object_name
|
||||
AND pc.instance_name = pc1.instance_name
|
||||
AND pc1.counter_name LIKE "%base"
|
||||
WHERE pc.counter_name NOT LIKE "% base"
|
||||
UNION ALL
|
||||
DECLARE @SQL NVARCHAR(MAX)
|
||||
SET @SQL = REPLACE('
|
||||
SELECT
|
||||
"sqlserver_performance" As [measurement],
|
||||
REPLACE(@@SERVERNAME,"\",":") AS [sql_instance],
|
||||
"SQLServer:Workload Group Stats" AS object,
|
||||
counter,
|
||||
instance,
|
||||
vs.value
|
||||
CAST(vs.value AS BIGINT) AS value,
|
||||
1
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
@@ -561,11 +539,29 @@ FROM
|
||||
) AS rg
|
||||
UNPIVOT (
|
||||
value FOR counter IN ( [Request Count], [Queued Request Count], [CPU Limit Violation Count], [CPU Usage (time)], ' + CASE WHEN SERVERPROPERTY('ProductMajorVersion') > 10 THEN '[Premptive CPU Usage (time)], ' ELSE '' END + '[Lock Wait Count], [Lock Wait Time], [Reduced Memory Grant Count] )
|
||||
) AS vs
|
||||
OPTION(RECOMPILE);'
|
||||
) AS vs'
|
||||
,'"','''')
|
||||
|
||||
EXEC(@DynamicPerf)
|
||||
INSERT INTO @PCounters
|
||||
EXEC( @SQL )
|
||||
|
||||
SELECT 'sqlserver_performance' AS [measurement],
|
||||
REPLACE(@@SERVERNAME,'\',':') AS [sql_instance],
|
||||
pc.object_name AS [object],
|
||||
pc.counter_name AS [counter],
|
||||
CASE pc.instance_name WHEN '_Total' THEN 'Total' ELSE ISNULL(pc.instance_name,'') END AS [instance],
|
||||
CAST(CASE WHEN pc.cntr_type = 537003264 AND pc1.cntr_value > 0 THEN (pc.cntr_value * 1.0) / (pc1.cntr_value * 1.0) * 100 ELSE pc.cntr_value END AS float(10)) AS [value]
|
||||
FROM @PCounters AS pc
|
||||
LEFT OUTER JOIN @PCounters AS pc1
|
||||
ON (
|
||||
pc.counter_name = REPLACE(pc1.counter_name,' base','')
|
||||
OR pc.counter_name = REPLACE(pc1.counter_name,' base',' (ms)')
|
||||
)
|
||||
AND pc.object_name = pc1.object_name
|
||||
AND pc.instance_name = pc1.instance_name
|
||||
AND pc1.counter_name LIKE '%base'
|
||||
WHERE pc.counter_name NOT LIKE '% base'
|
||||
OPTION(RECOMPILE);
|
||||
`
|
||||
|
||||
const sqlWaitStatsCategorizedV2 string = `SELECT
|
||||
|
||||
@@ -159,12 +159,18 @@ func NewHTTPClient(config *HTTPConfig) (*httpClient, error) {
|
||||
serializer = influx.NewSerializer()
|
||||
}
|
||||
|
||||
writeURL := makeWriteURL(
|
||||
writeURL, err := makeWriteURL(
|
||||
config.URL,
|
||||
database,
|
||||
config.RetentionPolicy,
|
||||
config.Consistency)
|
||||
queryURL := makeQueryURL(config.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queryURL, err := makeQueryURL(config.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var transport *http.Transport
|
||||
switch config.URL.Scheme {
|
||||
@@ -399,7 +405,7 @@ func (c *httpClient) addHeaders(req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func makeWriteURL(loc *url.URL, db, rp, consistency string) string {
|
||||
func makeWriteURL(loc *url.URL, db, rp, consistency string) (string, error) {
|
||||
params := url.Values{}
|
||||
params.Set("db", db)
|
||||
|
||||
@@ -417,22 +423,26 @@ func makeWriteURL(loc *url.URL, db, rp, consistency string) string {
|
||||
u.Scheme = "http"
|
||||
u.Host = "127.0.0.1"
|
||||
u.Path = "/write"
|
||||
case "http":
|
||||
case "http", "https":
|
||||
u.Path = path.Join(u.Path, "write")
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported scheme: %q", loc.Scheme)
|
||||
}
|
||||
u.RawQuery = params.Encode()
|
||||
return u.String()
|
||||
return u.String(), nil
|
||||
}
|
||||
|
||||
func makeQueryURL(loc *url.URL) string {
|
||||
func makeQueryURL(loc *url.URL) (string, error) {
|
||||
u := *loc
|
||||
switch u.Scheme {
|
||||
case "unix":
|
||||
u.Scheme = "http"
|
||||
u.Host = "127.0.0.1"
|
||||
u.Path = "/query"
|
||||
case "http":
|
||||
case "http", "https":
|
||||
u.Path = path.Join(u.Path, "query")
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported scheme: %q", loc.Scheme)
|
||||
}
|
||||
return u.String()
|
||||
return u.String(), nil
|
||||
}
|
||||
|
||||
@@ -46,6 +46,17 @@ func TestHTTP_MinimalConfig(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestHTTP_UnsupportedScheme(t *testing.T) {
|
||||
config := &influxdb.HTTPConfig{
|
||||
URL: &url.URL{
|
||||
Scheme: "foo",
|
||||
Host: "localhost",
|
||||
},
|
||||
}
|
||||
_, err := influxdb.NewHTTPClient(config)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestHTTP_CreateDatabase(t *testing.T) {
|
||||
ts := httptest.NewServer(http.NotFoundHandler())
|
||||
defer ts.Close()
|
||||
@@ -576,9 +587,6 @@ func TestHTTP_UnixSocket(t *testing.T) {
|
||||
ts.Start()
|
||||
defer ts.Close()
|
||||
|
||||
x, _ := url.Parse("unix://" + sock)
|
||||
fmt.Println(x)
|
||||
|
||||
successResponse := []byte(`{"results": [{"statement_id": 0}]}`)
|
||||
|
||||
tests := []struct {
|
||||
|
||||
@@ -210,7 +210,7 @@ func (i *InfluxDB) Write(metrics []telegraf.Metric) error {
|
||||
}
|
||||
|
||||
switch apiError := err.(type) {
|
||||
case APIError:
|
||||
case *APIError:
|
||||
if !i.SkipDatabaseCreation {
|
||||
if apiError.Type == DatabaseNotFound {
|
||||
err := client.CreateDatabase(ctx)
|
||||
|
||||
@@ -2,11 +2,13 @@ package influxdb_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
"github.com/influxdata/telegraf/plugins/outputs/influxdb"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -37,7 +39,7 @@ func (c *MockClient) CreateDatabase(ctx context.Context) error {
|
||||
func TestDeprecatedURLSupport(t *testing.T) {
|
||||
var actual *influxdb.UDPConfig
|
||||
output := influxdb.InfluxDB{
|
||||
URL: "udp://localhost:8086",
|
||||
URL: "udp://localhost:8089",
|
||||
|
||||
CreateUDPClientF: func(config *influxdb.UDPConfig) (influxdb.Client, error) {
|
||||
actual = config
|
||||
@@ -46,7 +48,7 @@ func TestDeprecatedURLSupport(t *testing.T) {
|
||||
}
|
||||
err := output.Connect()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "udp://localhost:8086", actual.URL.String())
|
||||
require.Equal(t, "udp://localhost:8089", actual.URL.String())
|
||||
}
|
||||
|
||||
func TestDefaultURL(t *testing.T) {
|
||||
@@ -70,7 +72,7 @@ func TestConnectUDPConfig(t *testing.T) {
|
||||
var actual *influxdb.UDPConfig
|
||||
|
||||
output := influxdb.InfluxDB{
|
||||
URLs: []string{"udp://localhost:8086"},
|
||||
URLs: []string{"udp://localhost:8089"},
|
||||
UDPPayload: 42,
|
||||
|
||||
CreateUDPClientF: func(config *influxdb.UDPConfig) (influxdb.Client, error) {
|
||||
@@ -81,7 +83,7 @@ func TestConnectUDPConfig(t *testing.T) {
|
||||
err := output.Connect()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "udp://localhost:8086", actual.URL.String())
|
||||
require.Equal(t, "udp://localhost:8089", actual.URL.String())
|
||||
require.Equal(t, 42, actual.MaxPayloadSize)
|
||||
require.NotNil(t, actual.Serializer)
|
||||
}
|
||||
@@ -90,7 +92,7 @@ func TestConnectHTTPConfig(t *testing.T) {
|
||||
var actual *influxdb.HTTPConfig
|
||||
|
||||
output := influxdb.InfluxDB{
|
||||
URLs: []string{"http://localhost:8089"},
|
||||
URLs: []string{"http://localhost:8086"},
|
||||
Database: "telegraf",
|
||||
RetentionPolicy: "default",
|
||||
WriteConsistency: "any",
|
||||
@@ -98,7 +100,7 @@ func TestConnectHTTPConfig(t *testing.T) {
|
||||
Username: "guy",
|
||||
Password: "smiley",
|
||||
UserAgent: "telegraf",
|
||||
HTTPProxy: "http://localhost:8089",
|
||||
HTTPProxy: "http://localhost:8086",
|
||||
HTTPHeaders: map[string]string{
|
||||
"x": "y",
|
||||
},
|
||||
@@ -133,3 +135,51 @@ func TestConnectHTTPConfig(t *testing.T) {
|
||||
|
||||
require.Equal(t, output.Database, actual.Database)
|
||||
}
|
||||
|
||||
func TestWriteRecreateDatabaseIfDatabaseNotFound(t *testing.T) {
|
||||
var createDatabaseCalled bool
|
||||
|
||||
output := influxdb.InfluxDB{
|
||||
URLs: []string{"http://localhost:8086"},
|
||||
|
||||
CreateHTTPClientF: func(config *influxdb.HTTPConfig) (influxdb.Client, error) {
|
||||
return &MockClient{
|
||||
CreateDatabaseF: func(ctx context.Context) error {
|
||||
createDatabaseCalled = true
|
||||
return nil
|
||||
},
|
||||
WriteF: func(ctx context.Context, metrics []telegraf.Metric) error {
|
||||
return &influxdb.APIError{
|
||||
StatusCode: http.StatusNotFound,
|
||||
Title: "404 Not Found",
|
||||
Description: `database not found "telegraf"`,
|
||||
Type: influxdb.DatabaseNotFound,
|
||||
}
|
||||
},
|
||||
URLF: func() string {
|
||||
return "http://localhost:8086"
|
||||
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
err := output.Connect()
|
||||
require.NoError(t, err)
|
||||
|
||||
m, err := metric.New(
|
||||
"cpu",
|
||||
map[string]string{},
|
||||
map[string]interface{}{
|
||||
"value": 42.0,
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
metrics := []telegraf.Metric{m}
|
||||
|
||||
createDatabaseCalled = false
|
||||
err = output.Write(metrics)
|
||||
// We only have one URL, so we expect an error
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -352,6 +352,8 @@ func (p *PrometheusClient) Write(metrics []telegraf.Metric) error {
|
||||
switch fv := fv.(type) {
|
||||
case int64:
|
||||
value = float64(fv)
|
||||
case uint64:
|
||||
value = float64(fv)
|
||||
case float64:
|
||||
value = fv
|
||||
default:
|
||||
@@ -391,6 +393,8 @@ func (p *PrometheusClient) Write(metrics []telegraf.Metric) error {
|
||||
switch fv := fv.(type) {
|
||||
case int64:
|
||||
value = float64(fv)
|
||||
case uint64:
|
||||
value = float64(fv)
|
||||
case float64:
|
||||
value = fv
|
||||
default:
|
||||
@@ -427,6 +431,8 @@ func (p *PrometheusClient) Write(metrics []telegraf.Metric) error {
|
||||
switch fv := fv.(type) {
|
||||
case int64:
|
||||
value = float64(fv)
|
||||
case uint64:
|
||||
value = float64(fv)
|
||||
case float64:
|
||||
value = fv
|
||||
default:
|
||||
|
||||
@@ -151,6 +151,16 @@ func TestWrite_Counters(t *testing.T) {
|
||||
metricName: "foo_other",
|
||||
valueType: telegraf.Counter,
|
||||
},
|
||||
{
|
||||
name: "uint64 fields are output",
|
||||
args: args{
|
||||
measurement: "foo",
|
||||
fields: map[string]interface{}{"value": uint64(42)},
|
||||
valueType: telegraf.Counter,
|
||||
},
|
||||
metricName: "foo",
|
||||
valueType: telegraf.Counter,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -239,6 +249,16 @@ func TestWrite_Gauge(t *testing.T) {
|
||||
metricName: "foo_other",
|
||||
valueType: telegraf.Gauge,
|
||||
},
|
||||
{
|
||||
name: "uint64 fields are output",
|
||||
args: args{
|
||||
measurement: "foo",
|
||||
fields: map[string]interface{}{"value": uint64(42)},
|
||||
valueType: telegraf.Counter,
|
||||
},
|
||||
metricName: "foo",
|
||||
valueType: telegraf.Counter,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -142,7 +142,7 @@ fieldfloat =
|
||||
fieldinteger =
|
||||
(integer 'i') >begin %integer;
|
||||
|
||||
fieldunsigned =
|
||||
fieldunsigned =
|
||||
(unsigned 'u') >begin %unsigned;
|
||||
|
||||
false =
|
||||
@@ -155,7 +155,7 @@ fieldbool =
|
||||
(true | false) >begin %bool;
|
||||
|
||||
fieldstringchar =
|
||||
[^\\"] | '\\' [\\"];
|
||||
[^\n\f\r\\"] | '\\' [\\"];
|
||||
|
||||
fieldstring =
|
||||
fieldstringchar* >begin %string;
|
||||
|
||||
@@ -1154,6 +1154,22 @@ var tests = []struct {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid newline in string field",
|
||||
input: []byte("cpu value=\"4\n2\""),
|
||||
results: []Result{
|
||||
Result{
|
||||
Name: Measurement,
|
||||
Value: []byte("cpu"),
|
||||
},
|
||||
Result{
|
||||
err: ErrFieldParse,
|
||||
},
|
||||
Result{
|
||||
err: ErrFieldParse,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid field value",
|
||||
input: []byte(`cpu value=howdy`),
|
||||
|
||||
@@ -3,30 +3,42 @@ package influx
|
||||
import "strings"
|
||||
|
||||
const (
|
||||
escapes = " ,="
|
||||
nameEscapes = " ,"
|
||||
stringFieldEscapes = `\"`
|
||||
escapes = "\t\n\f\r ,="
|
||||
nameEscapes = "\t\n\f\r ,"
|
||||
stringFieldEscapes = "\t\n\f\r\\\""
|
||||
)
|
||||
|
||||
var (
|
||||
escaper = strings.NewReplacer(
|
||||
"\t", `\t`,
|
||||
"\n", `\n`,
|
||||
"\f", `\f`,
|
||||
"\r", `\r`,
|
||||
`,`, `\,`,
|
||||
`"`, `\"`, // ???
|
||||
` `, `\ `,
|
||||
`=`, `\=`,
|
||||
)
|
||||
|
||||
nameEscaper = strings.NewReplacer(
|
||||
"\t", `\t`,
|
||||
"\n", `\n`,
|
||||
"\f", `\f`,
|
||||
"\r", `\r`,
|
||||
`,`, `\,`,
|
||||
` `, `\ `,
|
||||
)
|
||||
|
||||
stringFieldEscaper = strings.NewReplacer(
|
||||
"\t", `\t`,
|
||||
"\n", `\n`,
|
||||
"\f", `\f`,
|
||||
"\r", `\r`,
|
||||
`"`, `\"`,
|
||||
`\`, `\\`,
|
||||
)
|
||||
)
|
||||
|
||||
// Escape a tagkey, tagvalue, or fieldkey
|
||||
func escape(s string) string {
|
||||
if strings.ContainsAny(s, escapes) {
|
||||
return escaper.Replace(s)
|
||||
@@ -35,6 +47,7 @@ func escape(s string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Escape a measurement name
|
||||
func nameEscape(s string) string {
|
||||
if strings.ContainsAny(s, nameEscapes) {
|
||||
return nameEscaper.Replace(s)
|
||||
@@ -43,6 +56,7 @@ func nameEscape(s string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Escape a string field
|
||||
func stringFieldEscape(s string) string {
|
||||
if strings.ContainsAny(s, stringFieldEscapes) {
|
||||
return stringFieldEscaper.Replace(s)
|
||||
|
||||
@@ -261,6 +261,50 @@ var tests = []struct {
|
||||
),
|
||||
output: []byte("cpu abc=123i 1519194109000000042\ncpu def=456i 1519194109000000042\n"),
|
||||
},
|
||||
{
|
||||
name: "name newline",
|
||||
input: MustMetric(
|
||||
metric.New(
|
||||
"c\npu",
|
||||
map[string]string{},
|
||||
map[string]interface{}{
|
||||
"value": 42,
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
),
|
||||
output: []byte("c\\npu value=42i 0\n"),
|
||||
},
|
||||
{
|
||||
name: "tag newline",
|
||||
input: MustMetric(
|
||||
metric.New(
|
||||
"cpu",
|
||||
map[string]string{
|
||||
"host": "x\ny",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"value": 42,
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
),
|
||||
output: []byte("cpu,host=x\\ny value=42i 0\n"),
|
||||
},
|
||||
{
|
||||
name: "string newline",
|
||||
input: MustMetric(
|
||||
metric.New(
|
||||
"cpu",
|
||||
map[string]string{},
|
||||
map[string]interface{}{
|
||||
"value": "x\ny",
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
),
|
||||
output: []byte("cpu value=\"x\\ny\" 0\n"),
|
||||
},
|
||||
{
|
||||
name: "need more space",
|
||||
maxBytes: 32,
|
||||
|
||||
@@ -95,7 +95,7 @@ supported_packages = {
|
||||
"freebsd": [ "tar" ]
|
||||
}
|
||||
|
||||
next_version = '1.5.0'
|
||||
next_version = '1.6.0'
|
||||
|
||||
################
|
||||
#### Telegraf Functions
|
||||
|
||||
@@ -34,7 +34,9 @@ fi
|
||||
DEFAULT=/etc/default/telegraf
|
||||
|
||||
if [ -r $DEFAULT ]; then
|
||||
set -o allexport
|
||||
source $DEFAULT
|
||||
set +o allexport
|
||||
fi
|
||||
|
||||
if [ -z "$STDOUT" ]; then
|
||||
|
||||
Reference in New Issue
Block a user