Compare commits
12 Commits
c05cf671cf
...
main
Author | SHA1 | Date | |
---|---|---|---|
323a44100c | |||
3759f0d209 | |||
f2d0d1ca94 | |||
fa0b168ad3 | |||
4bdeb56013 | |||
f557893fad | |||
5de07b85dc | |||
38d35c1e79 | |||
101072eabc | |||
cc553c1341 | |||
553648e10d | |||
64dba890dd |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
|||||||
build
|
build
|
||||||
.DS_Store
|
.DS_Store
|
||||||
src/tsm/tsm
|
src/ntppm/ntppm
|
||||||
|
@ -4,10 +4,10 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- GOPATH=/woodpecker/go
|
- GOPATH=/woodpecker/go
|
||||||
- ls -l
|
- ls -l
|
||||||
- cd src/tsm
|
- cd src/ntppm
|
||||||
- go mod tidy
|
- go mod tidy
|
||||||
- go build -a -installsuffix nocgo -o tsm tsm.go
|
- go build -a -installsuffix nocgo -o ntppm ntppm.go
|
||||||
- cp tsm ../..
|
- cp ntppm ../..
|
||||||
when:
|
when:
|
||||||
- event: [push, tag]
|
- event: [push, tag]
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
FROM scratch
|
FROM scratch
|
||||||
|
|
||||||
ENV TSM_MQTT_CONF ""
|
ENV NTPPM_MQTT_CONF ""
|
||||||
|
|
||||||
COPY tsm ./
|
COPY ntppm ./
|
||||||
ENTRYPOINT ["./tsm"]
|
ENTRYPOINT ["./ntppm"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019 Daniel Chote
|
Copyright (c) 2025 Wolfgang Hottgenroth
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
64
README.md
64
README.md
@ -1,64 +0,0 @@
|
|||||||
# snmp-mqtt
|
|
||||||
|
|
||||||
This project is directly derived from https://github.com/dchote/snmp-mqtt
|
|
||||||
|
|
||||||
A simple go app that reads SNMP values and publishes it to the specified MQTT endpoint at the specified interval.
|
|
||||||
|
|
||||||
In constrast to the original version, all configuration must be provided via an environment variable containing
|
|
||||||
a JSON string.
|
|
||||||
|
|
||||||
The MQTT configuration is part of this JSON string.
|
|
||||||
|
|
||||||
The topic has been moved to the MQTT configuration and there is now only one topic for all endpoints and variables.
|
|
||||||
|
|
||||||
The published message on MQTT looks like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
{"device":"172.16.3.1","label":"router","variables":{"lan-in":{"label":"lan-in","variable":".1.3.6.1.2.1.31.1.1.1.6.2","value":"979673705579"},"lan-out":{"label":"lan-out","variable":".1.3.6.1.2.1.31.1.1.1.10.2","value":"1813410276168"},"wan-in":{"label":"wan-in","variable":".1.3.6.1.2.1.31.1.1.1.6.4","value":"83591215399"},"wan-out":{"label":"wan-out","variable":".1.3.6.1.2.1.31.1.1.1.10.4","value":"83741895468"}}}
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
export SNMP_MQTT_CONF=$(cat config.json)
|
|
||||||
./smq
|
|
||||||
```
|
|
||||||
|
|
||||||
An example config.json file:
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"mqtt": {
|
|
||||||
"broker": "mqtt://172.23.1.102:1883",
|
|
||||||
"tlsEnable": "false",
|
|
||||||
"topic": "snmp"
|
|
||||||
},
|
|
||||||
"interval": 10,
|
|
||||||
"snmpEndpoints": [
|
|
||||||
{
|
|
||||||
"endpoint": "172.16.3.1",
|
|
||||||
"label": "router",
|
|
||||||
"community": "public",
|
|
||||||
"oidTopics": [
|
|
||||||
{
|
|
||||||
"oid": ".1.3.6.1.2.1.31.1.1.1.6.4",
|
|
||||||
"label": "wan-in",
|
|
||||||
"diff": "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"oid": ".1.3.6.1.2.1.31.1.1.1.10.4",
|
|
||||||
"label": "wan-out",
|
|
||||||
"diff": "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"oid": ".1.3.6.1.2.1.31.1.1.1.6.2",
|
|
||||||
"label": "lan-in",
|
|
||||||
"diff": "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"oid": ".1.3.6.1.2.1.31.1.1.1.10.2",
|
|
||||||
"label": "lan-out",
|
|
||||||
"diff": "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
74
snippets/test01.go
Normal file
74
snippets/test01.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Struktur für die JSON-Daten
|
||||||
|
type NTPResponse struct {
|
||||||
|
History []struct {
|
||||||
|
Timestamp int `json:"ts"`
|
||||||
|
Step int `json:"step"`
|
||||||
|
Score float64 `json:"score"`
|
||||||
|
MonitorID int `json:"monitor_id"`
|
||||||
|
} `json:"history"`
|
||||||
|
Monitors []struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Ts string `json:"ts"`
|
||||||
|
Score float64 `json:"score"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
} `json:"monitors"`
|
||||||
|
Server struct {
|
||||||
|
IP string `json:"ip"`
|
||||||
|
} `json:"server"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// URL für die API-Abfrage
|
||||||
|
url := "https://www.ntppool.org/scores/93.241.86.156/json?limit=1&monitor=24"
|
||||||
|
|
||||||
|
// HTTP-GET-Anfrage senden
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Fehler beim Abrufen der URL:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Antwort lesen
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Fehler beim Lesen der Antwort:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON-Daten in Struct einlesen
|
||||||
|
var data NTPResponse
|
||||||
|
err = json.Unmarshal(body, &data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Fehler beim Parsen des JSON:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausgabe der eingelesenen Daten
|
||||||
|
fmt.Println("NTP Server IP:", data.Server.IP)
|
||||||
|
if len(data.History) > 0 {
|
||||||
|
fmt.Println("Letzte Messung:")
|
||||||
|
fmt.Printf(" Zeitstempel: %d\n", data.History[0].Timestamp)
|
||||||
|
fmt.Printf(" Score: %.2f\n", data.History[0].Score)
|
||||||
|
fmt.Printf(" Monitor ID: %d\n", data.History[0].MonitorID)
|
||||||
|
}
|
||||||
|
if len(data.Monitors) > 0 {
|
||||||
|
fmt.Println("Monitor Info:")
|
||||||
|
fmt.Printf(" Name: %s\n", data.Monitors[0].Name)
|
||||||
|
fmt.Printf(" Score: %.2f\n", data.Monitors[0].Score)
|
||||||
|
fmt.Printf(" Status: %s\n", data.Monitors[0].Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ type ConfigObject struct {
|
|||||||
var Config ConfigObject
|
var Config ConfigObject
|
||||||
|
|
||||||
func LoadConfiguration() {
|
func LoadConfiguration() {
|
||||||
cfg := os.Getenv("TSM_MQTT_CONF")
|
cfg := os.Getenv("NTPPM_MQTT_CONF")
|
||||||
log.Printf("cfg: %s", cfg)
|
log.Printf("cfg: %s", cfg)
|
||||||
err := json.Unmarshal([]byte(cfg), &Config)
|
err := json.Unmarshal([]byte(cfg), &Config)
|
||||||
if err != nil {
|
if err != nil {
|
@ -1,9 +1,8 @@
|
|||||||
module tsm
|
module ntppm
|
||||||
|
|
||||||
go 1.22.5
|
go 1.22.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/beevik/ntp v1.4.3
|
|
||||||
github.com/eclipse/paho.mqtt.golang v1.4.3
|
github.com/eclipse/paho.mqtt.golang v1.4.3
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
)
|
)
|
@ -5,14 +5,14 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
"tsm/config"
|
"ntppm/config"
|
||||||
"tsm/mqtt"
|
"ntppm/mqtt"
|
||||||
"tsm/tsmq"
|
"ntppm/ntppq"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.SetPrefix("TSM: ")
|
log.SetPrefix("NTPPM: ")
|
||||||
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
||||||
|
|
||||||
log.Println("starting")
|
log.Println("starting")
|
||||||
@ -22,8 +22,8 @@ func main() {
|
|||||||
mqtt.Start()
|
mqtt.Start()
|
||||||
defer mqtt.Stop()
|
defer mqtt.Stop()
|
||||||
|
|
||||||
tsmq.Start()
|
ntppq.Start()
|
||||||
defer tsmq.Stop()
|
defer ntppq.Stop()
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, os.Interrupt, os.Kill)
|
signal.Notify(c, os.Interrupt, os.Kill)
|
@ -1,25 +1,25 @@
|
|||||||
package tsmq
|
package ntppq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
"strconv"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"tsm/config"
|
"ntppm/config"
|
||||||
"tsm/mqtt"
|
"ntppm/mqtt"
|
||||||
|
|
||||||
"github.com/beevik/ntp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type variable_t struct {
|
type variable_t struct {
|
||||||
Name string `json:"variable"`
|
Label string `json:"label"`
|
||||||
Value float64 `json:"value"`
|
Variable string `json:"variable"`
|
||||||
|
Value string `json:"value"`
|
||||||
Unit string `json:"unit"`
|
Unit string `json:"unit"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type message_t struct {
|
type message_t struct {
|
||||||
Server string `json:"server"`
|
Device string `json:"device"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Variables map[string]variable_t `json:"variables"`
|
Variables map[string]variable_t `json:"variables"`
|
||||||
}
|
}
|
||||||
@ -32,28 +32,36 @@ func Start() {
|
|||||||
log.Println("Polling server " + server.Name)
|
log.Println("Polling server " + server.Name)
|
||||||
|
|
||||||
message := message_t {
|
message := message_t {
|
||||||
Server: server.Name,
|
Device: server.Name,
|
||||||
Label: server.Label,
|
Label: server.Label,
|
||||||
Variables: make(map[string]variable_t),
|
Variables: make(map[string]variable_t),
|
||||||
}
|
}
|
||||||
|
|
||||||
label := "rootdisp"
|
|
||||||
status := "Ok"
|
status := "Ok"
|
||||||
value := 0.0
|
rootdisp := 0.0
|
||||||
|
stratum := 0
|
||||||
resp, err := ntp.Query(server.Name)
|
resp, err := ntp.Query(server.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
status = "Error"
|
status = "Error"
|
||||||
} else {
|
} else {
|
||||||
value = resp.RootDispersion.Seconds() * 1000
|
rootdisp = resp.RootDispersion.Seconds() * 1000
|
||||||
|
stratum = int(resp.Stratum)
|
||||||
}
|
}
|
||||||
|
|
||||||
v := variable_t {
|
message.Variables["rootdisp"] = variable_t {
|
||||||
Name: label,
|
Label: "rootdisp",
|
||||||
Value: value,
|
Variable: "",
|
||||||
|
Value: strconv.FormatFloat(rootdisp, 'f', 4, 64),
|
||||||
|
Unit: "ms",
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
message.Variables["stratum"] = variable_t {
|
||||||
|
Label: "stratum",
|
||||||
|
Variable: "",
|
||||||
|
Value: strconv.Itoa(stratum),
|
||||||
Unit: "ms",
|
Unit: "ms",
|
||||||
Status: status,
|
Status: status,
|
||||||
}
|
}
|
||||||
message.Variables[label] = v
|
|
||||||
|
|
||||||
|
|
||||||
j, err := json.Marshal(message)
|
j, err := json.Marshal(message)
|
Reference in New Issue
Block a user