launch oc-monitor locally or in a container
This commit is contained in:
parent
f7eb7e4b81
commit
7ecfee1154
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM golang:alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN go build .
|
||||||
|
RUN mkdir workflows/
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY conf/ocmonitor_conf.json /app/conf/
|
||||||
|
COPY --from=builder /app/oc-monitor .
|
||||||
|
COPY --from=builder /app/workflows/ .
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/app/oc-monitor" ]
|
14
README.md
14
README.md
@ -1,2 +1,16 @@
|
|||||||
# oc-monitor
|
# oc-monitor
|
||||||
|
|
||||||
|
## Deploy in k8s (dev)
|
||||||
|
|
||||||
|
While a registry with all of the OC docker images has not been set-up we can export this image to k3s ctr
|
||||||
|
|
||||||
|
> docker save oc-monitor:latest | sudo k3s ctr images import -
|
||||||
|
|
||||||
|
Then in the pod manifest for oc-monitor use :
|
||||||
|
|
||||||
|
```
|
||||||
|
image: docker.io/library/oc-monitor
|
||||||
|
imagePullPolicy: Never
|
||||||
|
```
|
||||||
|
|
||||||
|
Not doing so will end up in the pod having a `ErrorImagePull`
|
30
conf/conf.go
Normal file
30
conf/conf.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package conf
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
// declare the flag to use for each variable
|
||||||
|
var map_arguments = map[string]string {
|
||||||
|
"LokiURL" : "u",
|
||||||
|
"ArgoFile": "f",
|
||||||
|
"ContainerName" : "n",
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
LokiURL string
|
||||||
|
ArgoFile string
|
||||||
|
ContainerName string
|
||||||
|
}
|
||||||
|
|
||||||
|
var instance *Config
|
||||||
|
var once sync.Once
|
||||||
|
|
||||||
|
func GetConfig() *Config {
|
||||||
|
once.Do(func() {
|
||||||
|
instance = &Config{}
|
||||||
|
})
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConfFromArgs(argument string){
|
||||||
|
|
||||||
|
}
|
1
conf/ocmonitor_conf.json
Normal file
1
conf/ocmonitor_conf.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
15
go.mod
15
go.mod
@ -2,11 +2,16 @@ module oc-monitor
|
|||||||
|
|
||||||
go 1.22.0
|
go 1.22.0
|
||||||
|
|
||||||
require github.com/grafana/loki-client-go v0.0.0-20230116142646-e7494d0ef70c
|
require (
|
||||||
|
cloud.o-forge.io/core/oc-lib v0.0.0-20240725103514-2891dc8a6819
|
||||||
|
github.com/akamensky/argparse v1.4.0
|
||||||
|
github.com/goraz/onion v0.1.3
|
||||||
|
github.com/rs/zerolog v1.33.0
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
golang.org/x/sys v0.22.0 // indirect
|
||||||
)
|
)
|
||||||
|
114
main.go
114
main.go
@ -2,24 +2,114 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os/exec"
|
"os"
|
||||||
|
|
||||||
|
"oc-monitor/conf"
|
||||||
|
|
||||||
|
"cloud.o-forge.io/core/oc-lib/logs"
|
||||||
|
"github.com/akamensky/argparse"
|
||||||
|
"github.com/goraz/onion"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var logger zerolog.Logger
|
||||||
|
var parser argparse.Parser
|
||||||
|
|
||||||
|
const defaultConfigFile = "/etc/oc/ocmonitor_conf.json"
|
||||||
|
const localConfigFile = "./conf/ocmonitor_conf.json"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Initialize LokiLogger
|
|
||||||
lokiLogger := NewLokiLogger("http://localhost:3100/loki/api/v1/push") // Replace with your Loki URL
|
// Test if monitor is launched outside (with parameters) or in a k8s environment (env variables sets)
|
||||||
|
if os.Getenv("KUBERNETES_SERVICE_HOST") == ""{
|
||||||
|
// Not in a k8s environment, get conf from parameters
|
||||||
|
parser = *argparse.NewParser("oc-monitor","Launch the execution of a workflow given as a parameter and sends the produced logs to a loki database")
|
||||||
|
loadConfig(false, &parser)
|
||||||
|
} else {
|
||||||
|
// Executed in a k8s environment
|
||||||
|
loadConfig(true,nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger = logs.CreateLogger("oc-monitor", conf.GetConfig().LokiURL)
|
||||||
|
logger.Debug().Msg("Loki URL : " + conf.GetConfig().LokiURL)
|
||||||
|
logger.Debug().Msg("Filename : " + conf.GetConfig().ArgoFile)
|
||||||
|
logger.Debug().Msg("Container Name : " + conf.GetConfig().ContainerName)
|
||||||
|
|
||||||
|
// Wait for the argo file to be copied to the pod
|
||||||
|
wf_found := false
|
||||||
|
for(!wf_found){
|
||||||
|
if _, err := os.Stat("./workflows/" + conf.GetConfig().ArgoFile); err == nil {
|
||||||
|
wf_found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.Debug().Msg("Submitting the argo workflow : " + conf.GetConfig().ArgoFile)
|
||||||
|
// // Initialize LokiLogger
|
||||||
|
// lokiLogger := NewLokiLogger("http://localhost:3100/loki/api/v1/push") // Replace with your Loki URL
|
||||||
|
|
||||||
// Run the Argo command
|
// Run the Argo command
|
||||||
cmd := exec.Command("argo", "submit", "your-workflow.yaml")
|
// cmd := exec.Command("argo", "submit", "your-workflow.yaml")
|
||||||
output, err := cmd.CombinedOutput()
|
// output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Fatalf("failed to run Argo command: %v", err)
|
// log.Fatalf("failed to run Argo command: %v", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Send logs to Loki
|
// logger.Info().Msg(string(output))
|
||||||
if err := lokiLogger.Log(`{job="argo"}`, string(output)); err != nil {
|
// // Send logs to Loki
|
||||||
log.Fatalf("failed to send logs to Loki: %v", err)
|
// if err := lokiLogger.Log(`{job="argo"}`, string(output)); err != nil {
|
||||||
}
|
// log.Fatalf("failed to send logs to Loki: %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
log.Println("Logs sent to Loki successfully.")
|
log.Println("Logs sent to Loki successfully.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadConfig(is_k8s bool, parser *argparse.Parser){
|
||||||
|
|
||||||
|
var o *onion.Onion
|
||||||
|
|
||||||
|
logger = logs.CreateLogger("oc-monitor","")
|
||||||
|
configFile := ""
|
||||||
|
|
||||||
|
l3 := onion.NewEnvLayerPrefix("_", "OCMONITOR")
|
||||||
|
l2, err := onion.NewFileLayer(defaultConfigFile, nil)
|
||||||
|
if err == nil {
|
||||||
|
logger.Info().Msg("Config file found : " + defaultConfigFile)
|
||||||
|
configFile = defaultConfigFile
|
||||||
|
}
|
||||||
|
l1, err := onion.NewFileLayer(localConfigFile, nil)
|
||||||
|
if err == nil {
|
||||||
|
logger.Info().Msg("Local config file found " + localConfigFile + ", overriding default file")
|
||||||
|
configFile = localConfigFile
|
||||||
|
}
|
||||||
|
if configFile == "" {
|
||||||
|
logger.Info().Msg("No config file found, using env")
|
||||||
|
o = onion.New(l3)
|
||||||
|
} else if l1 == nil && l2 == nil {
|
||||||
|
o = onion.New(l1, l2, l3)
|
||||||
|
} else if l1 == nil {
|
||||||
|
o = onion.New(l2, l3)
|
||||||
|
} else if l2 == nil {
|
||||||
|
o = onion.New(l1, l3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// These variables can only be retrieved in the onion
|
||||||
|
// Variables that don't depend on the environmen (from conf file), can be loaded after
|
||||||
|
if (is_k8s){
|
||||||
|
// We can't use underscore in the env variable names because it's the delimitor with OCMONITOR too
|
||||||
|
conf.GetConfig().LokiURL = o.GetStringDefault("lokiurl", "http://127.0.0.1:3100")
|
||||||
|
conf.GetConfig().ArgoFile = o.GetString("argofile")
|
||||||
|
conf.GetConfig().ContainerName = o.GetString("containername")
|
||||||
|
} else{
|
||||||
|
url := parser.String("u", "url", &argparse.Options{Required: true,Default: "http://127.0.0.1:3100"})
|
||||||
|
conf.GetConfig().LokiURL = *url
|
||||||
|
file := parser.String("f", "file", &argparse.Options{Required: true})
|
||||||
|
conf.GetConfig().ArgoFile = *file
|
||||||
|
name := parser.String("n", "name", &argparse.Options{Required: true})
|
||||||
|
conf.GetConfig().ContainerName = *name
|
||||||
|
|
||||||
|
err := parser.Parse(os.Args)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal().Msg(parser.Usage(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user