Skip to content

Commit

Permalink
make timeout configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
kang-makes committed Sep 19, 2024
1 parent caaf061 commit e4b0c3d
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 84 deletions.
23 changes: 3 additions & 20 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,11 @@ name: UnitTesting

on: [push, pull_request]

env:
GO111MODULE: off

jobs:

build:
name: Build
runs-on: ubuntu-latest
defaults:
run:
working-directory: src/github.com/newrelic/infra-integrations-sdk
steps:

- name: Set up Go
uses: actions/setup-go@v2

- name: Check out code into the Go module directory
uses: actions/checkout@v2
with:
path: src/github.com/newrelic/infra-integrations-sdk

- name: Test
env:
GOPATH: "${{ github.workspace }}"
run: env PATH="$PATH:$GOPATH/bin" make test
- uses: actions/setup-go@v5
- uses: actions/checkout@v4
- run: make test
40 changes: 6 additions & 34 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,44 +1,16 @@
GO_VERSION = $(shell go version | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')

GOTOOLS = gopkg.in/alecthomas/gometalinter.v2 \
github.com/axw/gocov/gocov \
github.com/AlekSi/gocov-xml \

# golint only supports the last two Go versions, update the value when its not supported anymore.
GOLINT_MIN_GO_VERSION = 1.9

# If GO_VERSION is equal or higher than the GOLINT_MIN_GO_VERSION we use golint.
ifeq ($(GO_VERSION),$(shell echo "$(GOLINT_MIN_GO_VERSION)\n$(GO_VERSION)" | sort -V | tail -n1))
GOTOOLS += golang.org/x/lint/golint
endif

# Temporary patch to avoid build failing because of the outdated documentation example
PKGS = $(shell go list ./... | egrep -v "\/docs\/|jmx")

.PHONY: all
all: lint test

deps: tools
@go get -v -d -t $(PKGS)

test: deps
@gocov test -race $(PKGS) | gocov-xml > coverage.xml
@gocov test github.com/newrelic/infra-integrations-sdk/jmx > /dev/null # TODO: fix race for jmx package
.PHONY: test
test:
@go test -race $(PKGS)
@go test github.com/newrelic/infra-integrations-sdk/jmx > /dev/null # TODO: fix race for jmx package

.PHONY: clean
clean:
rm -rf coverage.xml

tools:
@go get $(GOTOOLS)
@gometalinter.v2 --install > /dev/null

tools-update:
@go get -u $(GOTOOLS)
@gometalinter.v2 --install

lint: deps
@gometalinter.v2 --config=.gometalinter.json ./...

lint-all: deps
@gometalinter.v2 --config=.gometalinter.json --enable=interfacer --enable=gosimple ./...

.PHONY: all deps devdeps test clean
33 changes: 20 additions & 13 deletions args/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ import (
// DefaultArgumentList includes the minimal set of necessary arguments for an integration.
// If all data flags (Inventory, Metrics and Events) are false, all of them are published.
type DefaultArgumentList struct {
Verbose bool `default:"false" help:"Print more information to logs."`
Pretty bool `default:"false" help:"Print pretty formatted JSON."`
Metrics bool `default:"false" help:"Publish metrics data."`
Inventory bool `default:"false" help:"Publish inventory data."`
Events bool `default:"false" help:"Publish events data."`
Metadata bool `default:"false" help:"Add customer defined key-value attributes to the samples."`
NriAddHostname bool `default:"false" help:"Add hostname attribute to the samples."`
NriCluster string `default:"" help:"Optional. Cluster name"`
NriService string `default:"" help:"Optional. Service name"`
TempDir string `default:"" help:"Optional. Integrations path to store temporal data (defaults to os.tempDir if left empty)."`
Verbose bool `default:"false" help:"Print more information to logs."`
Pretty bool `default:"false" help:"Print pretty formatted JSON."`
Metrics bool `default:"false" help:"Publish metrics data."`
Inventory bool `default:"false" help:"Publish inventory data."`
Events bool `default:"false" help:"Publish events data."`
Metadata bool `default:"false" help:"Add customer defined key-value attributes to the samples."`
NriAddHostname bool `default:"false" help:"Add hostname attribute to the samples."`
NriCluster string `default:"" help:"Optional. Cluster name"`
NriService string `default:"" help:"Optional. Service name"`
TempDir string `default:"" help:"Optional. Integrations path to store temporal data (defaults to os.tempDir if left empty)."`
CacheTTL time.Duration `default:"6m" help:"Optional. The time the integration considers a temporal stored value as valid (defaults to 6 minutes left empty)."`
}

// All returns if all data should be published
Expand All @@ -49,9 +50,9 @@ func (d *DefaultArgumentList) HasInventory() bool {
// HTTPClientArgumentList are meant to be used as flags from a custom integrations. With this you could
// send this arguments from the command line.
type HTTPClientArgumentList struct {
HTTPCaBundleFile string `default: "" help: "Name of the certificate file"`
HTTPCaBundleDir string `default: "" help: "Path where the certificate exists"`
HTTPTimeout time.Duration `default:30 help: "Client http timeout in seconds"`
HTTPCaBundleFile string `default:"" help:"Name of the certificate file"`
HTTPCaBundleDir string `default:"" help:"Path where the certificate exists"`
HTTPTimeout time.Duration `default:"30" help:"Client http timeout in seconds"`
}

func getArgsFromEnv() func(f *flag.Flag) {
Expand Down Expand Up @@ -153,6 +154,12 @@ func defineFlags(args interface{}) error {
return fmt.Errorf("can't parse %s: not a boolean", argName)
}
flag.BoolVar(argDefault, argName, boolVal, helpValue)
case *time.Duration:
durationVal, err := time.ParseDuration(defaultValue)
if err != nil {
return fmt.Errorf("can't parse %s: not a duration", argName)
}
flag.DurationVar(argDefault, argName, durationVal, helpValue)
case *string:
flag.StringVar(argDefault, argName, defaultValue, helpValue)
case *JSON:
Expand Down
8 changes: 7 additions & 1 deletion args/args_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,11 @@ func TestDefaultArgumentsWithPretty(t *testing.T) {
var args sdk_args.DefaultArgumentList
assert.NoError(t, sdk_args.SetupArgs(&args))

assertEqualArgs(t, sdk_args.DefaultArgumentList{Pretty: true}, args)
clearFlagSet()
expected := sdk_args.DefaultArgumentList{Pretty: true}
assert.NoError(t, sdk_args.SetupArgs(&expected))

assertEqualArgs(t, expected, args)
}

func TestAddCustomArgumentsToDefault(t *testing.T) {
Expand All @@ -271,10 +275,12 @@ func TestAddCustomArgumentsToDefault(t *testing.T) {
}
assert.NoError(t, sdk_args.SetupArgs(&args))

clearFlagSet()
expected := argumentList{
DefaultArgumentList: sdk_args.DefaultArgumentList{Pretty: true},
Hostname: "otherhost",
}
assert.NoError(t, sdk_args.SetupArgs(&expected))

assertEqualArgs(t, expected, args)
}
Expand Down
8 changes: 3 additions & 5 deletions data/metric/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package metric

import (
"encoding/json"
"errors"
"fmt"
"math"
"sort"
"strconv"

"github.com/newrelic/infra-integrations-sdk/data/attribute"
"github.com/newrelic/infra-integrations-sdk/persist"
"github.com/pkg/errors"
)

const (
Expand Down Expand Up @@ -61,9 +61,7 @@ func AddCustomAttributes(metricSet *Set, customAttributes []attribute.Attribute)

// AddNamespaceAttributes add attributes to MetricSet namespace.
func (ms *Set) AddNamespaceAttributes(attributes ...attribute.Attribute) {
for _, attr := range attributes {
ms.nsAttributes = append(ms.nsAttributes, attr)
}
ms.nsAttributes = append(ms.nsAttributes, attributes...)
}

// SetMetric adds a metric to the Set object or updates the metric value if the metric already exists.
Expand All @@ -81,7 +79,7 @@ func (ms *Set) SetMetric(name string, value interface{}, sourceType SourceType)
}
newValue, errElapsed = ms.elapsedDifference(name, value, sourceType)
if errElapsed != nil {
return errors.Wrapf(errElapsed, "cannot calculate elapsed difference for metric: %s value %v", name, value)
return fmt.Errorf("cannot calculate elapsed difference for metric: %s value %v: %w", name, value, errElapsed)
}
case GAUGE:
newValue, err = castToFloat(value)
Expand Down
22 changes: 22 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module github.com/newrelic/infra-integrations-sdk

go 1.23

require github.com/stretchr/testify v1.9.0

require (
github.com/AlekSi/gocov-xml v1.1.0 // indirect
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect
github.com/axw/gocov v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/nicksnyder/go-i18n v1.10.3 // indirect
github.com/pelletier/go-toml v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 // indirect
gopkg.in/alecthomas/gometalinter.v2 v2.0.12 // indirect
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780 // indirect
gopkg.in/yaml.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
52 changes: 52 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
github.com/AlekSi/gocov-xml v1.1.0 h1:iElWGi7s/MuL8/d8WDtI2fOAsN3ap9x8nK5RrAhaDng=
github.com/AlekSi/gocov-xml v1.1.0/go.mod h1:g1dRVOCHjKkMtlPfW6BokJ/qxoeZ1uPNAK7A/ii3CUo=
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg=
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
github.com/axw/gocov v1.1.0 h1:y5U1krExoJDlb/kNtzxyZQmNRprFOFCutWbNjcQvmVM=
github.com/axw/gocov v1.1.0/go.mod h1:H9G4tivgdN3pYSSVrTFBr6kGDCmAkgbJhtxFzAvgcdw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/nicksnyder/go-i18n v1.10.3 h1:0U60fnLBNrLBVt8vb8Q67yKNs+gykbQuLsIkiesJL+w=
github.com/nicksnyder/go-i18n v1.10.3/go.mod h1:hvLG5HTlZ4UfSuVLSRuX7JRUomIaoKQM19hm6f+no7o=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/alecthomas/gometalinter.v2 v2.0.12 h1:/xBWwtjmOmVxn8FXfIk9noV8m2E2Id9jFfUY/Mh9QAI=
gopkg.in/alecthomas/gometalinter.v2 v2.0.12/go.mod h1:NDRytsqEZyolNuAgTzJkZMkSQM7FIKyzVzGhjB/qfYo=
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780 h1:CEBpW6C191eozfEuWdUmIAHn7lwlLxJ7HVdr2e2Tsrw=
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
7 changes: 5 additions & 2 deletions integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ func New(name, version string, opts ...Option) (i *Integration, err error) {
defaultArgs := args.GetDefaultArgs(i.args)
i.prettyOutput = defaultArgs.Pretty
i.addHostnameToMeta = defaultArgs.NriAddHostname
if defaultArgs.CacheTTL == 0 {
defaultArgs.CacheTTL = persist.DefaultTTL
}

if defaultArgs.Verbose {
log.SetupLogging(defaultArgs.Verbose)
Expand All @@ -100,14 +103,14 @@ func New(name, version string, opts ...Option) (i *Integration, err error) {
}

if i.storer == nil {
storePath, err := persist.NewStorePath(i.Name, i.CreateUniqueID(), defaultArgs.TempDir, i.logger, persist.DefaultTTL)
storePath, err := persist.NewStorePath(i.Name, i.CreateUniqueID(), defaultArgs.TempDir, i.logger, defaultArgs.CacheTTL)
if err != nil {
return nil, fmt.Errorf("can't create temporary directory for store: %s", err)
}

storePath.CleanOldFiles()

i.storer, err = persist.NewFileStore(storePath.GetFilePath(), i.logger, persist.DefaultTTL)
i.storer, err = persist.NewFileStore(storePath.GetFilePath(), i.logger, defaultArgs.CacheTTL)
if err != nil {
return nil, fmt.Errorf("can't create store: %s", err)
}
Expand Down
4 changes: 2 additions & 2 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ func TestIntegration_CreateUniqueID_Default(t *testing.T) {
i, err := New("testIntegration", "0.0.0", Args(&al))
assert.NoError(t, err)

assert.Equal(t, i.CreateUniqueID(), "f2fbf79d935a14908cb886e98cff0879")
assert.Equal(t, "d72d09add1ac94e0293c4f5d41fd9f6e", i.CreateUniqueID())
}

func TestIntegration_CreateUniqueID_EnvironmentVar(t *testing.T) {
Expand All @@ -481,7 +481,7 @@ func TestIntegration_CreateUniqueID_EnvironmentVar(t *testing.T) {
i, err := New("testIntegration", "0.0.0", Args(&al))
assert.NoError(t, err)

assert.Equal(t, i.CreateUniqueID(), "3d3c4d31fdec9ccd1250c9d080ca514f")
assert.Equal(t, "0a837adb9898b2aeb68da8b817adce1c", i.CreateUniqueID())
}

type testWriter struct {
Expand Down
7 changes: 4 additions & 3 deletions persist/store_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package persist

import (
"fmt"
"github.com/newrelic/infra-integrations-sdk/log"
"os"
"path/filepath"
"time"

"github.com/newrelic/infra-integrations-sdk/log"
)

const (
Expand Down Expand Up @@ -37,8 +38,8 @@ func NewStorePath(integrationName, integrationID, customTempDir string, ilog log
return nil, fmt.Errorf("integration id not specified")
}

if ttl == 0 {
ttl = DefaultTTL
if ttl <= 0 {
return nil, fmt.Errorf("invalid TTL: %d", ttl)
}

return &storePath{
Expand Down
7 changes: 3 additions & 4 deletions persist/storer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
Expand All @@ -17,7 +16,7 @@ import (

const (
// DefaultTTL specifies the "Time To Live" of the disk storage.
DefaultTTL = 1 * time.Minute
DefaultTTL = 6 * time.Minute
filePerm = 0644
dirFilePerm = 0755
integrationsDir = "nr-integrations"
Expand Down Expand Up @@ -173,7 +172,7 @@ func (j *fileStore) Save() error {
return err
}

return ioutil.WriteFile(j.path, bytes, filePerm)
return os.WriteFile(j.path, bytes, filePerm)
}

func (j *inMemoryStore) Save() error {
Expand Down Expand Up @@ -251,7 +250,7 @@ func (j *fileStore) loadFromDisk() error {
j.locker.Lock()
defer j.locker.Unlock()

bytes, err := ioutil.ReadFile(j.path)
bytes, err := os.ReadFile(j.path)
if err != nil {
return fmt.Errorf("can't read %q: %s. Ignoring", j.path, err.Error())
}
Expand Down

0 comments on commit e4b0c3d

Please sign in to comment.