tixel-elastic: initial commit with first prototype version for discussion
This commit is contained in:
commit
3af5853421
13 changed files with 1900 additions and 0 deletions
148
elasticsearch.go
Normal file
148
elasticsearch.go
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/elastic/go-elasticsearch/v7"
|
||||
)
|
||||
|
||||
func NewElasticsearchClient(config ElasticsearchConfig) (*elasticsearch.Client, error) {
|
||||
esConfig := elasticsearch.Config{
|
||||
Addresses: []string{config.URL},
|
||||
}
|
||||
|
||||
if config.Username != "" && config.Password != "" {
|
||||
esConfig.Username = config.Username
|
||||
esConfig.Password = config.Password
|
||||
}
|
||||
|
||||
client, err := elasticsearch.NewClient(esConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create elasticsearch client: %w", err)
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func TestElasticsearchConnection(es *elasticsearch.Client) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
res, err := es.Info(es.Info.WithContext(ctx))
|
||||
if err != nil {
|
||||
return fmt.Errorf("connection test failed: %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.IsError() {
|
||||
return fmt.Errorf("connection test failed: %s", res.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ElasticsearchSender interface {
|
||||
SendBatch(baseIndex string, entries []LogEntry) error
|
||||
SendSystemMetrics(baseIndex string, metrics SystemResources) error
|
||||
}
|
||||
|
||||
type ElasticsearchClient struct {
|
||||
client *elasticsearch.Client
|
||||
}
|
||||
|
||||
func NewElasticsearchSender(client *elasticsearch.Client) ElasticsearchSender {
|
||||
return &ElasticsearchClient{client: client}
|
||||
}
|
||||
|
||||
func (esc *ElasticsearchClient) SendBatch(baseIndex string, entries []LogEntry) error {
|
||||
if len(entries) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var body strings.Builder
|
||||
for _, entry := range entries {
|
||||
indexName := determineIndexName(baseIndex, entry)
|
||||
|
||||
indexLine := fmt.Sprintf(`{"index":{"_index":"%s"}}`, indexName)
|
||||
body.WriteString(indexLine)
|
||||
body.WriteString("\n")
|
||||
|
||||
data, err := json.Marshal(entry)
|
||||
if err != nil {
|
||||
slog.Error("error marshalling JSON", "error", err)
|
||||
continue
|
||||
}
|
||||
body.WriteString(string(data))
|
||||
body.WriteString("\n")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
res, err := esc.client.Bulk(
|
||||
strings.NewReader(body.String()),
|
||||
esc.client.Bulk.WithContext(ctx),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bulk request error: %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.IsError() {
|
||||
return fmt.Errorf("bulk request failed: %s", res.String())
|
||||
}
|
||||
|
||||
slog.Debug("Batch successfully sent", "count", len(entries))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (esc *ElasticsearchClient) SendSystemMetrics(baseIndex string, metrics SystemResources) error {
|
||||
data, err := json.Marshal(metrics)
|
||||
if err != nil {
|
||||
return fmt.Errorf("JSON marshalling error: %w", err)
|
||||
}
|
||||
|
||||
systemIndex := fmt.Sprintf("%s-system", baseIndex)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
res, err := esc.client.Index(
|
||||
systemIndex,
|
||||
strings.NewReader(string(data)),
|
||||
esc.client.Index.WithContext(ctx),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("elasticsearch index error: %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.IsError() {
|
||||
return fmt.Errorf("elasticsearch error: %s", res.String())
|
||||
}
|
||||
|
||||
slog.Debug("System-Metrics sent",
|
||||
"CPU", metrics.CPUPercent,
|
||||
"MEM_used", metrics.MemoryUsed,
|
||||
"MEM_total", metrics.MemoryTotal,
|
||||
"MEM_percentage", metrics.MemoryPercent,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func determineIndexName(baseIndex string, entry LogEntry) string {
|
||||
switch entry.Type {
|
||||
case "system_metrics":
|
||||
return fmt.Sprintf("%s-system", baseIndex)
|
||||
case "service_log":
|
||||
return fmt.Sprintf("%s-service-%s", baseIndex, entry.Service)
|
||||
default:
|
||||
return fmt.Sprintf("%s-%s", baseIndex, entry.Tool)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue