73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
package clickhouse
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/aceberg/WatchYourLAN/internal/models"
|
|
)
|
|
|
|
// Global HTTP Client to enable Keep-Alive Connection-Reuse
|
|
var httpClient = &http.Client{
|
|
Timeout: 10 * time.Second,
|
|
}
|
|
|
|
// Add - write data to ClickHouse
|
|
func Add(appConfig models.Conf, oneHist models.Host) {
|
|
if appConfig.ClickhouseAddr == "" {
|
|
return
|
|
}
|
|
|
|
db := appConfig.ClickhouseDB
|
|
if db == "" {
|
|
db = "default"
|
|
}
|
|
|
|
table := appConfig.ClickhouseTable
|
|
if table == "" {
|
|
table = "watch_your_lan"
|
|
}
|
|
|
|
insertSQL := fmt.Sprintf("INSERT INTO %s.%s (ts, known, mac, iface, ip, name) FORMAT JSONEachRow", db, table)
|
|
jsonRow := map[string]any{
|
|
"ts": time.Now().UTC().Format("2006-01-02 15:04:05"),
|
|
"known": oneHist.Known,
|
|
"mac": oneHist.Mac,
|
|
"iface": oneHist.Iface,
|
|
"ip": oneHist.IP,
|
|
"name": oneHist.Name,
|
|
}
|
|
jsonData, err := json.Marshal(jsonRow)
|
|
if err != nil {
|
|
slog.Error("ClickHouse JSON error", "err", err)
|
|
return
|
|
}
|
|
|
|
reqURL := fmt.Sprintf("%s/?query=%s", appConfig.ClickhouseAddr, url.QueryEscape(insertSQL))
|
|
req, err := http.NewRequest(http.MethodPost, reqURL, bytes.NewBuffer(jsonData))
|
|
if err != nil {
|
|
slog.Error("ClickHouse Request error", "err", err)
|
|
return
|
|
}
|
|
|
|
req.Header.Set("X-ClickHouse-User", appConfig.ClickhouseUser)
|
|
req.Header.Set("X-ClickHouse-Key", appConfig.ClickhousePassword)
|
|
|
|
res, err := httpClient.Do(req)
|
|
if err != nil {
|
|
slog.Error("ClickHouse network error", "err", err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, _ := io.ReadAll(res.Body)
|
|
if res.StatusCode != http.StatusOK {
|
|
slog.Error("ClickHouse HTTP error", "status", res.StatusCode, "body", string(body))
|
|
}
|
|
}
|