From 371b44422b9645afd4ce591afe73efab3aa07279 Mon Sep 17 00:00:00 2001 From: Foudre Date: Tue, 29 Apr 2025 23:31:22 +0200 Subject: [PATCH] add probe folder --- probe/cmd/obsero-probe/main.go | 20 +++++++ probe/pkg/geo/geo.go | 24 +++++++++ probe/pkg/probe/ping.go | 42 +++++++++++++++ probe/pkg/proof/format.go | 52 ++++++++++++++++++ probe/readme.md | 96 ++++++++++++++++++++++++++++++++++ 5 files changed, 234 insertions(+) create mode 100644 probe/cmd/obsero-probe/main.go create mode 100644 probe/pkg/geo/geo.go create mode 100644 probe/pkg/probe/ping.go create mode 100644 probe/pkg/proof/format.go create mode 100644 probe/readme.md diff --git a/probe/cmd/obsero-probe/main.go b/probe/cmd/obsero-probe/main.go new file mode 100644 index 0000000..6d37a8f --- /dev/null +++ b/probe/cmd/obsero-probe/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "os" + "git.cryptolab.re/foudre/whitepaper_obsero/pkg/geo" + "git.cryptolab.re/foudre/whitepaper_obsero/pkg/probe" + "git.cryptolab.re/foudre/whitepaper_obsero/pkg/proof" +) + +func main() { + target := "https://example.com" + + location := geo.GetGeoLocation() + result := probe.HttpPing(target) + observation := proof.BuildProof(result, location) + + proof.SaveProof(observation, "proof_http_result.json") + fmt.Println("βœ… Proof generated and saved.") +} diff --git a/probe/pkg/geo/geo.go b/probe/pkg/geo/geo.go new file mode 100644 index 0000000..d9bf204 --- /dev/null +++ b/probe/pkg/geo/geo.go @@ -0,0 +1,24 @@ +package geo + +import ( + "encoding/json" + "net/http" +) + +type GeoInfo struct { + Country string `json:"country"` + Region string `json:"regionName"` + City string `json:"city"` +} + +func GetGeoLocation() GeoInfo { + resp, err := http.Get("http://ip-api.com/json") + if err != nil { + return GeoInfo{Country: "Unknown", Region: "Unknown", City: "Unknown"} + } + defer resp.Body.Close() + + var info GeoInfo + json.NewDecoder(resp.Body).Decode(&info) + return info +} diff --git a/probe/pkg/probe/ping.go b/probe/pkg/probe/ping.go new file mode 100644 index 0000000..d5cc8d5 --- /dev/null +++ b/probe/pkg/probe/ping.go @@ -0,0 +1,42 @@ +package probe + +import ( + "net/http" + "time" +) + +type PingResult struct { + Target string + Status string + StatusCode int + LatencyMs int64 + ErrorMsg string + Timestamp string +} + +func HttpPing(target string) PingResult { + start := time.Now() + resp, err := http.Get(target) + latency := time.Since(start).Milliseconds() + timestamp := time.Now().UTC().Format(time.RFC3339) + + result := PingResult{ + Target: target, + Timestamp: timestamp, + } + + if err != nil { + result.Status = "down" + result.LatencyMs = 0 + result.StatusCode = 0 + result.ErrorMsg = err.Error() + } else { + defer resp.Body.Close() + result.Status = "up" + result.LatencyMs = latency + result.StatusCode = resp.StatusCode + result.ErrorMsg = "" + } + + return result +} diff --git a/probe/pkg/proof/format.go b/probe/pkg/proof/format.go new file mode 100644 index 0000000..880d7da --- /dev/null +++ b/probe/pkg/proof/format.go @@ -0,0 +1,52 @@ +package proof + +import ( + "encoding/json" + "os" + + "git.cryptolab.re/foudre/whitepaper_obsero/pkg/geo" + "git.cryptolab.re/foudre/whitepaper_obsero/pkg/probe" +) + +type Observation struct { + Timestamp string `json:"timestamp"` + Target string `json:"target"` + Status string `json:"status"` + HTTPStatus int `json:"http_status_code"` + LatencyMs int64 `json:"latency_ms"` + Error string `json:"error_message"` + Observer ObserverInfo `json:"observer"` + Version string `json:"version"` +} + +type ObserverInfo struct { + Address string `json:"address"` + Country string `json:"country"` + Region string `json:"region"` + City string `json:"city"` + ProbeVersion string `json:"probe_version"` +} + +func BuildProof(result probe.PingResult, loc geo.GeoInfo) Observation { + return Observation{ + Timestamp: result.Timestamp, + Target: result.Target, + Status: result.Status, + HTTPStatus: result.StatusCode, + LatencyMs: result.LatencyMs, + Error: result.ErrorMsg, + Version: "0.1", + Observer: ObserverInfo{ + Address: "0xABCD...1234", + Country: loc.Country, + Region: loc.Region, + City: loc.City, + ProbeVersion: "0.1", + }, + } +} + +func SaveProof(obs Observation, filename string) { + file, _ := json.MarshalIndent(obs, "", " ") + _ = os.WriteFile(filename, file, 0644) +} diff --git a/probe/readme.md b/probe/readme.md new file mode 100644 index 0000000..04ab4bc --- /dev/null +++ b/probe/readme.md @@ -0,0 +1,96 @@ +# πŸ›°οΈ Obsero Probe + +Lightweight monitoring agent for generating Proof-of-Observability JSON files. + +This probe performs HTTP health checks, automatically geolocates itself, and exports signed observation files compliant with the Obsero specification. + +--- + +## βš™οΈ Requirements + +- Go 1.21+ +- Internet access (for geo lookup and ping) + +--- + +## πŸš€ Quick Start + +### 1. Clone & Enter + +```bash +cd probe +``` + +### 2. Install dependencies + +```bash +go mod tidy +``` + +### 3. Run the probe + +```bash +go run ./cmd/obsero-probe +``` + +This will: +- Ping `https://example.com` +- Auto-detect country, city and region +- Output a file named `proof_http_result.json` + +--- + +## πŸ“„ Output Format + +The output file is a valid Obsero proof: + +```json +{ + "timestamp": "2025-04-29T14:00:00Z", + "target": "https://example.com", + "status": "up", + "http_status_code": 200, + "latency_ms": 145, + "error_message": null, + "observer": { + "address": "0xABCD...1234", + "country": "France", + "region": "Île-de-France", + "city": "Paris", + "probe_version": "0.1" + }, + "version": "0.1" +} +``` + +--- + +## πŸ“¦ Next steps + +- Add CLI support (`--target`, `--output`) +- Add cryptographic signature of the proof +- Upload to IPFS +- Submit hash + CID on Base chain + +--- + +## πŸ“ Structure + +``` +probe/ +β”œβ”€β”€ cmd/ +β”‚ └── obsero-probe/ +β”‚ └── main.go # CLI entrypoint +β”œβ”€β”€ pkg/ +β”‚ β”œβ”€β”€ geo/ # IP geolocation +β”‚ β”œβ”€β”€ probe/ # HTTP ping logic +β”‚ └── proof/ # Proof struct + output +β”œβ”€β”€ go.mod +β”œβ”€β”€ go.sum +``` + +--- + +## πŸ“œ License + +MIT β€” Cryptolab.re