Skip to content

Commit

Permalink
Merge branch 'major-version-upgrade' into 'master'
Browse files Browse the repository at this point in the history
JSN-651: Major version upgrade

See merge request PRTG/open-source/go-prtg-sensor-api!2
  • Loading branch information
benjaminbear committed Oct 17, 2019
2 parents ebf6364 + 0457671 commit 3ade81c
Show file tree
Hide file tree
Showing 14 changed files with 1,436 additions and 241 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ _testmain.go
*.exe
*.test
*.prof

.idea/
35 changes: 35 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
include:
- project: "infrastructure/templates"
ref: master
file: "/.golang.yml"
- project: "infrastructure/templates"
ref: master
file: "/.runner-tags.yml"

image: ${INFRA_GOLANG_IMAGE}

stages:
- test

golangci-lint:
stage: test
before_script:
- export GO111MODULE=on
- go mod download
script:
- go version
- golangci-lint run ./...
extends: .INFRA_RUNNER_TAGS_K8S

testing:
stage: test
coverage: '/^total:\t+\(statements\)\t+(\d+\.\d+)%/'
before_script:
- export GO111MODULE=on
- go mod download
script:
- go version
- go test ./... -coverprofile cover.out
- go tool cover -func cover.out
extends: .INFRA_RUNNER_TAGS_K8S

16 changes: 16 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
run:
deadline: 5m
tests: false

linters-settings:
errcheck:
# ignore stupid FlagCheck that is already checked, rest is default
ignore: fmt:.*

linters:
enable-all: true
fast: false

issues:
max-issues-per-linter: 50
max-same-issues: 50
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: go

env:
- GO111MODULE=on

git:
depth: 1

go:
- 1.12.x
- 1.13.x

before_script:
- go install github.com/golangci/golangci-lint/cmd/golangci-lint

script:
- golangci-lint run ./...
- go test ./... -coverprofile cover.out
- go tool cover -func cover.out
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2016, Paessler AG <[email protected]>
Copyright (c) 2019, Paessler AG <[email protected]>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Expand Down
148 changes: 118 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# go-prtg-api
# go-prtg-sensor-api
API for writing PRTG custom sensors in Go.

## Example
This simple exampe sensor sends an HTTP request to http://paessler.com
[![Build Status](https://travis-ci.org/PRTG/go-prtg-sensor-api.svg "Travis CI status")](https://travis-ci.org/PRTG/go-prtg-sensor-api)
[![GoDoc](https://godoc.org/github.com/PRTG/go-prtg-sensor-api?status.svg)](https://godoc.org/github.com/PRTG/go-prtg-sensor-api)
[![Go Report Card](https://goreportcard.com/badge/github.com/PRTG/go-prtg-sensor-api)](https://goreportcard.com/report/PRTG/go-prtg-sensor-api/)

## Example EXE Sensor
This simple example sensor sends an HTTP request to http://paessler.com
and returns two channels:
- `Response time` - time it takes to perform the request and read the body
- `Bytes read` - number of bytes the body contained
Expand All @@ -13,54 +17,57 @@ package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"time"

"github.com/PaesslerAG/go-prtg-sensor-api"
"github.com/PRTG/go-prtg-sensor-api"
)

func main() {
// Create empty response and log start time
r := &prtg.SensorResponse{}
// Initiate Sensor instance
sensor := prtg.New()

// Log start time
start := time.Now()
// Perform HTTP request
resp, err := http.Get("http://paessler.com")
if err != nil {
r.PRTG.Error = "1"
r.PRTG.Text = err.Error()
fmt.Println(r.String())
sensor.SetError(true)
sensor.SetSensorText(err.Error())
json, err := sensor.MarshalToString()
if err != nil {
log.Fatal(err)
}
fmt.Println(json)
return
}
// Read the response
buffer, err := ioutil.ReadAll(resp.Body)
if err != nil {
r.PRTG.Error = "1"
r.PRTG.Text = err.Error()
fmt.Println(r.String())
sensor.SetError(true)
sensor.SetSensorText(err.Error())
json, err := sensor.MarshalToString()
if err != nil {
log.Fatal(err)
}
fmt.Println(json)
return
}
// Evaluate results
responseTime := time.Since(start)
responseBytes := len(buffer)

// Response time channel
r.AddChannel(prtg.SensorChannel{
Channel: "Response time",
Value: fmt.Sprintf("%f", responseTime.Seconds()*1000),
Float: 1,
ShowChart: 1,
ShowTable: 1,
Unit: prtg.UnitTimeResponse,
})
sensor.AddChannel("Response time").SetValue(responseTime.Seconds() * 1000).SetUnit(prtg.TimeResponse)
// Bytes read channel
r.AddChannel(prtg.SensorChannel{
Channel: "Bytes read",
Value: fmt.Sprintf("%d", responseBytes),
ShowChart: 1,
ShowTable: 1,
Unit: prtg.UnitBytesFile,
})

fmt.Println(r.String())
sensor.AddChannel("Bytes read").SetValue(responseBytes).SetUnit(prtg.BytesFile)

json, err := sensor.MarshalToString()
if err != nil {
log.Fatal(err)
}
fmt.Println(json)
}
```

Expand All @@ -74,6 +81,87 @@ To test this example in your PRTG installation follow these steps:
6. Under `EXE/Script` choose the `.exe` you copied in step 2
7. Done


## Example HTTP Data Advanced Sensor

This example sensor uses a http server to serve the sensor data, that can be pulled
by a http data advanced sensor.
- `Some value` - shows sample percentage value
- `Something` - shows if the Something service is up and running

The Sensor returns an error if "Something" is not ok.

```golang
package main

import (
"fmt"
"log"
"math/rand"
"net/http"

"github.com/PRTG/go-prtg-sensor-api"
)

func main() {
// Create a webserver listening on "/"
http.HandleFunc("/", reportStatus)
http.ListenAndServe(":8080", nil)
}

func reportStatus(w http.ResponseWriter, r *http.Request) {
// Initiate PRTG instance
sensor := prtg.New()

// Set sensor text
sensor.SetSensorText("This is a test sensor")

// Add a channel with a random float value in Percent
sensor.AddChannel("Some value").SetValue(rand.Float64() * 100).
SetUnit(prtg.Percent).SetMaxWarnLimit(80).SetMaxErrLimit(90)

// Take a look if Something is working
isUp, err := isSomethingUp()
// Create a Sensor that shows the uptime of Something
sensor.AddChannel("Something").SetValue(isUp).
SetValueLookup("prtg.standardlookups.connectionstate.stateonlineok")
// Create error message on sensor if the Something is down
if err != nil {
sensor.SetError(true)
sensor.SetSensorText("Test sensor error: " + err.Error())
}

// Create json output
json, err := sensor.MarshalToString()
if err != nil {
log.Fatal(err)
}

// Deliver to website
_, err = fmt.Fprint(w, json)
if err != nil {
log.Fatal(err)
}
}

func isSomethingUp() (bool, error) {
// Generate a "Thing" to watch, that is working in 90% of the time
if rand.Intn(10) > 1 {
return true, nil
}
return false, fmt.Errorf("the Something is struggling")
}
```

To test this example in your PRTG installation follow these steps:

1. Build the example
2. Run the binary
3. Go to PRTG web interface
4. Add Sensor to a device of your choice
5. Choose `HTTP Data Advanced` as sensor type
6. Under `URL` choose the ip of your device with the port `8080`
7. Done

## Documentation
- [godoc.org/github.com/PaesslerAG/go-prtg-sensor-api](https://godoc.org/github.com/PaesslerAG/go-prtg-sensor-api)
- [PRTG Manual](https://www.paessler.com/manuals/prtg/exe_script_advanced_sensor)
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/PRTG/go-prtg-sensor-api

go 1.13
68 changes: 68 additions & 0 deletions prtg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2019, Paessler AG.
// All Rights Reserved

// Package PRTG implements the API for PRTG custom sensors.
// It provides all structs and constants needed to implement your own advanced exe sensor in Go.
package prtg

import (
"encoding/json"
)

// SensorStatus has the whole JSON object
type SensorResponse struct {
SensorResults SensorResults `json:"prtg"`
}

// SensorResults has all the channels
type SensorResults struct {
SensorChannels []SensorChannel `json:"result"`
Text string `json:"text,omitempty"`
Error string `json:"error,omitempty"`
}

type Sensor interface {
AddChannel(string) *SensorChannel
MarshalToString() (string, error)
SetSensorText(string) *SensorResults
SetError(bool) *SensorResults
}

// Creates the Sensor instance and returns the interface.
func New() Sensor {
return &SensorResults{}
}

// Name of the channel as displayed in user interfaces.
func (sr *SensorResults) AddChannel(channelName string) *SensorChannel {
newChan := SensorChannel{Channel: channelName}
sr.SensorChannels = append(sr.SensorChannels, newChan)

return &sr.SensorChannels[len(sr.SensorChannels)-1]
}

// Create a JSON string from the PRTG object
func (sr *SensorResults) MarshalToString() (string, error) {
bytes, err := json.Marshal(&SensorResponse{*sr})
return string(bytes), err
}

// Text the sensor returns in the Message field with every scanning interval.
// There can be one message per sensor, regardless of the number of channels.
// Default is OK.
func (sr *SensorResults) SetSensorText(text string) *SensorResults {
sr.Text = text
return sr
}

// If enabled, the sensor will return an error status.
// This element can be combined with the SensorText element in order to show an error message.
// Default is 0.
func (sr *SensorResults) SetError(err bool) *SensorResults {
sr.Error = "0"
if err {
sr.Error = "1"
}

return sr
}
Loading

0 comments on commit 3ade81c

Please sign in to comment.