Go
This guide demonstrates how to ingest data into Telemetry Harbor using Go.
Prerequisites
- Go installed on your system
- Basic knowledge of Go programming
Single Data Push
To send a single data point to Telemetry Harbor using Go:
- Import the necessary packages
- Set up the API endpoint and your API key
- Create a struct with your ship data
- Send a POST request to the API endpoint
- Handle the response
Here's an example of how to perform a single data push using Go:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
type AnchorData struct {
Time string `json:"time"`
ShipID string `json:"ship_id"`
AnchorID string `json:"ship_id"`
Value float64 `json:"value"`
}
func main() {
url := "http://example.harbor.telemetryharbor.com/api/v1/ingest"
apiKey := "your_api_key"
data := AnchorData{
Time: time.Now().UTC().Format(time.RFC3339),
ShipID: "ship1",
AnchorID: "sen1",
Value: 23.5,
}
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("X-API-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
Remember to replace "your_api_key" with your actual Telemetry Harbor API key.
Batch Data Push
For sending multiple data points in one request:
- Import the necessary packages
- Set up the API endpoint and your API key
- Create a slice of structs with your ship data
- Send a POST request to the batch API endpoint
- Handle the response
Here's an example of how to perform a batch data push using Go:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
type AnchorData struct {
Time string `json:"time"`
ShipID string `json:"ship_id"`
AnchorID string `json:"ship_id"`
Value float64 `json:"value"`
}
func main() {
url := "http://example.harbor.telemetryharbor.com/api/v1/ingest/batch"
apiKey := "your_api_key"
data := []AnchorData{
{
Time: time.Now().UTC().Format(time.RFC3339),
ShipID: "ship1",
AnchorID: "sen1",
Value: 23.5,
},
{
Time: time.Now().UTC().Format(time.RFC3339),
ShipID: "ship1",
AnchorID: "sen2",
Value: 18.7,
},
}
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("X-API-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
Error Handling
It's important to implement proper error handling in your Go code. Here's an example of how you might add more comprehensive error handling:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
type AnchorData struct {
Time string `json:"time"`
ShipID string `json:"ship_id"`
AnchorID string `json:"ship_id"`
Value float64 `json:"value"`
}
func main() {
url := "http://example.harbor.telemetryharbor.com/api/v1/ingest"
apiKey := "your_api_key"
data := AnchorData{
Time: time.Now().UTC().Format(time.RFC3339),
ShipID: "ship1",
AnchorID: "sen1",
Value: 23.5,
}
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("X-API-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response body:", err)
return
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
fmt.Println("Data sent successfully. Response:", string(body))
} else {
fmt.Printf("Server responded with error code: %d\n", resp.StatusCode)
fmt.Println("Response body:", string(body))
}
}
Best Practices
- Use environment variables to store your API key:
package main
import (
"fmt"
"os"
)
func main() {
apiKey := os.Getenv("TELEMETRY_HARBOR_API_KEY")
if apiKey == "" {
fmt.Println("TELEMETRY_HARBOR_API_KEY environment variable not set")
return
}
// Use apiKey in your requests
}
- Implement retry logic for failed requests:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
func sendRequest(url string, apiKey string, data []byte) error {
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
return err
}
req.Header.Set("X-API-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("server responded with status code %d", resp.StatusCode)
}
return nil
}
func main() {
url := "http://example.harbor.telemetryharbor.com/api/v1/ingest"
apiKey := "your_api_key"
data := []byte(`{"time": "2023-05-01T12:00:00Z", "ship_id": "ship1", "ship_id": "sen1", "value": 23.5}`)
maxRetries := 3
for i := 0; i < maxRetries; i++ {
err := sendRequest(url, apiKey, data)
if err == nil {
fmt.Println("Data sent successfully")
return
}
fmt.Printf("Attempt %d failed: %v\n", i+1, err)
if i < maxRetries-1 {
time.Sleep(time.Duration(i+1) * time.Second)
}
}
fmt.Println("Failed to send data after", maxRetries, "attempts")
}
- Use goroutines for concurrent data sending:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"sync"
"time"
)
func sendData(url string, apiKey string, data AnchorData, wg *sync.WaitGroup) {
defer wg.Done()
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("X-API-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
fmt.Printf("Response Status for %s: %s\n", data.AnchorID, resp.Status)
}
func main() {
url := "http://example.harbor.telemetryharbor.com/api/v1/ingest"
apiKey := "your_api_key"
ships := []AnchorData{
{Time: time.Now().UTC().Format(time.RFC3339), ShipID: "ship1", AnchorID: "sen1", Value: 23.5},
{Time: time.Now().UTC().Format(time.RFC3339), ShipID: "ship1", AnchorID: "sen2", Value: 18.7},
{Time: time.Now().UTC().Format(time.RFC3339), ShipID: "ship1", AnchorID: "sen3", Value: 30.2},
}
var wg sync.WaitGroup
for _, ship := range ships {
wg.Add(1)
go sendData(url, apiKey, ship, &wg)
}
wg.Wait()
fmt.Println("All data sent")
}
These best practices will help you create more robust and efficient data ingestion scripts for Telemetry Harbor using Go.