| @@ -63,12 +63,19 @@ services: | |||||
| container_name: presense-decoder | container_name: presense-decoder | ||||
| env_file: | env_file: | ||||
| - ./env/presense-decoder.env | - ./env/presense-decoder.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| volumes: | volumes: | ||||
| - ../:/app | - ../:/app | ||||
| command: air --build.cmd "go build -buildvcs=false -o ./decoder ./cmd/decoder" --build.bin "./decoder" | command: air --build.cmd "go build -buildvcs=false -o ./decoder ./cmd/decoder" --build.bin "./decoder" | ||||
| @@ -81,16 +88,21 @@ services: | |||||
| container_name: presense-server | container_name: presense-server | ||||
| env_file: | env_file: | ||||
| - ./env/presense-server.env | - ./env/presense-server.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| ports: | ports: | ||||
| - "127.0.0.1:1902:1902" | - "127.0.0.1:1902:1902" | ||||
| depends_on: | depends_on: | ||||
| valkey: | |||||
| condition: service_started | |||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| volumes: | volumes: | ||||
| - ../:/app | - ../:/app | ||||
| command: air --build.cmd "go build -buildvcs=false -o ./server ./cmd/server" --build.bin "./server" | command: air --build.cmd "go build -buildvcs=false -o ./server ./cmd/server" --build.bin "./server" | ||||
| @@ -103,12 +115,19 @@ services: | |||||
| container_name: presense-bridge | container_name: presense-bridge | ||||
| env_file: | env_file: | ||||
| - ./env/presense-bridge.env | - ./env/presense-bridge.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| volumes: | volumes: | ||||
| - ../:/app | - ../:/app | ||||
| command: air --build.cmd "go build -buildvcs=false -o ./bridge ./cmd/bridge" --build.bin "./bridge" | command: air --build.cmd "go build -buildvcs=false -o ./bridge ./cmd/bridge" --build.bin "./bridge" | ||||
| @@ -121,12 +140,19 @@ services: | |||||
| container_name: presense-location | container_name: presense-location | ||||
| env_file: | env_file: | ||||
| - ./env/presense-location.env | - ./env/presense-location.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| volumes: | volumes: | ||||
| - ../:/app | - ../:/app | ||||
| command: air --build.cmd "go build -buildvcs=false -o ./location ./cmd/location" --build.bin "./location" | command: air --build.cmd "go build -buildvcs=false -o ./location ./cmd/location" --build.bin "./location" | ||||
| @@ -50,64 +50,84 @@ services: | |||||
| - ./init-scripts/create_topic.sh:/tmp/create_topic.sh | - ./init-scripts/create_topic.sh:/tmp/create_topic.sh | ||||
| env_file: | env_file: | ||||
| - ./env/kafka-init.env | - ./env/kafka-init.env | ||||
| valkey: | |||||
| image: valkey/valkey:9.0.0 | |||||
| container_name: valkey | |||||
| ports: | |||||
| - "127.0.0.1:6379:6379" | |||||
| presense-decoder: | presense-decoder: | ||||
| image: presense-decoder | image: presense-decoder | ||||
| container_name: presense-decoder | container_name: presense-decoder | ||||
| env_file: | env_file: | ||||
| - ./env/presense-decoder.env | - ./env/presense-decoder.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| presense-server: | presense-server: | ||||
| image: presense-server | image: presense-server | ||||
| container_name: presense-server | container_name: presense-server | ||||
| env_file: | env_file: | ||||
| - ./env/presense-server.env | - ./env/presense-server.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| ports: | ports: | ||||
| - "127.0.0.1:1902:1902" | - "127.0.0.1:1902:1902" | ||||
| depends_on: | depends_on: | ||||
| valkey: | |||||
| condition: service_started | |||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| presense-bridge: | presense-bridge: | ||||
| image: presense-bridge | image: presense-bridge | ||||
| container_name: presense-bridge | container_name: presense-bridge | ||||
| env_file: | env_file: | ||||
| - ./env/presense-bridge.env | - ./env/presense-bridge.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| presense-location: | presense-location: | ||||
| image: presense-location | image: presense-location | ||||
| container_name: presense-location | container_name: presense-location | ||||
| env_file: | env_file: | ||||
| - ./env/presense-location.env | - ./env/presense-location.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| volumes: | volumes: | ||||
| @@ -1,27 +0,0 @@ | |||||
| services: | |||||
| woodpecker-server: | |||||
| image: woodpeckerci/woodpecker-server:v1.0.2 | |||||
| ports: | |||||
| - 8000:8000 | |||||
| volumes: | |||||
| - woodpecker-data:/var/lib/woodpecker | |||||
| environment: | |||||
| - WOODPECKER_GITEA=true | |||||
| - WOODPECKER_OPEN=true | |||||
| - WOODPECKER_ADMIN=Smehov | |||||
| - WOODPECKER_GITEA_URL=https://git.afasystems.it/ | |||||
| - WOODPECKER_GITEA_CLIENT=005e1420-b635-4d82-ac4b-70bfd61746ed | |||||
| - WOODPECKER_GITEA_SECRET=rsfZ5jD4UcmrSl9mqutnHgO2eXBN-i8qNa-hil2SuMw= | |||||
| - WOODPECKER_AGENT_SECRET=agent-secret | |||||
| - WOODPECKER_HOST=http://10.8.0.53:8000 | |||||
| woodpecker-agent: | |||||
| image: woodpeckerci/woodpecker-agent:v1.0.2 | |||||
| volumes: | |||||
| - /var/run/docker.sock:/var/run/docker.sock | |||||
| environment: | |||||
| - WOODPECKER_SERVER=woodpecker-server:9000 | |||||
| - WOODPECKER_AGENT_SECRET=agent-secret | |||||
| volumes: | |||||
| woodpecker-data: | |||||
| @@ -58,52 +58,78 @@ services: | |||||
| container_name: presense-decoder | container_name: presense-decoder | ||||
| env_file: | env_file: | ||||
| - ./env/presense-decoder.env | - ./env/presense-decoder.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| presense-server: | presense-server: | ||||
| image: afasystemadmin/ble-ai-localizer:server_v1 | image: afasystemadmin/ble-ai-localizer:server_v1 | ||||
| container_name: presense-server | container_name: presense-server | ||||
| env_file: | env_file: | ||||
| - ./env/presense-server.env | - ./env/presense-server.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| ports: | ports: | ||||
| - "127.0.0.1:1902:1902" | - "127.0.0.1:1902:1902" | ||||
| depends_on: | depends_on: | ||||
| valkey: | |||||
| condition: service_started | |||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| presense-bridge: | presense-bridge: | ||||
| image: afasystemadmin/ble-ai-localizer:bridge_v1 | image: afasystemadmin/ble-ai-localizer:bridge_v1 | ||||
| container_name: presense-bridge | container_name: presense-bridge | ||||
| env_file: | env_file: | ||||
| - ./env/presense-bridge.env | - ./env/presense-bridge.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| presense-location: | presense-location: | ||||
| image: afasystemadmin/ble-ai-localizer:location_v1 | image: afasystemadmin/ble-ai-localizer:location_v1 | ||||
| container_name: presense-location | container_name: presense-location | ||||
| env_file: | env_file: | ||||
| - ./env/presense-location.env | - ./env/presense-location.env | ||||
| environment: | |||||
| LOG_LEVEL: "info" | |||||
| depends_on: | depends_on: | ||||
| kafka-init: | kafka-init: | ||||
| condition: service_completed_successfully | condition: service_completed_successfully | ||||
| db: | db: | ||||
| condition: service_healthy | condition: service_healthy | ||||
| restart: always | restart: always | ||||
| logging: | |||||
| driver: "json-file" | |||||
| options: | |||||
| max-size: "10m" | |||||
| max-file: "3" | |||||
| volumes: | volumes: | ||||
| @@ -84,7 +84,6 @@ func (a *LocationApp) Run(ctx context.Context) { | |||||
| } | } | ||||
| case <-locTicker.C: | case <-locTicker.C: | ||||
| settings := a.AppState.GetSettings() | settings := a.AppState.GetSettings() | ||||
| slog.Info("current algorithm", "algorithm", settings.CurrentAlgorithm) | |||||
| switch settings.CurrentAlgorithm { | switch settings.CurrentAlgorithm { | ||||
| case "filter": | case "filter": | ||||
| pkglocation.GetLikelyLocations(a.AppState, a.KafkaManager.GetWriter("locevents")) | pkglocation.GetLikelyLocations(a.AppState, a.KafkaManager.GetWriter("locevents")) | ||||
| @@ -116,12 +115,12 @@ func (a *LocationApp) Run(ctx context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| slog.Info("AI algorithm", "count", inferred.Count, "items", len(inferred.Items)) | |||||
| slog.Debug("AI algorithm", "count", inferred.Count, "items", len(inferred.Items)) | |||||
| } | } | ||||
| case msg := <-a.ChRaw: | case msg := <-a.ChRaw: | ||||
| pkglocation.AssignBeaconToList(msg, a.AppState) | pkglocation.AssignBeaconToList(msg, a.AppState) | ||||
| case msg := <-a.ChSettings: | case msg := <-a.ChSettings: | ||||
| slog.Info("settings update", "msg", msg) | |||||
| slog.Debug("settings update", "msg", msg) | |||||
| a.AppState.UpdateSettings(msg) | a.AppState.UpdateSettings(msg) | ||||
| } | } | ||||
| } | } | ||||
| @@ -30,7 +30,7 @@ func Logging(next http.Handler) http.Handler { | |||||
| start := time.Now() | start := time.Now() | ||||
| wrap := &responseWriter{ResponseWriter: w, status: http.StatusOK} | wrap := &responseWriter{ResponseWriter: w, status: http.StatusOK} | ||||
| next.ServeHTTP(wrap, r) | next.ServeHTTP(wrap, r) | ||||
| slog.Info("request", | |||||
| slog.Debug("request", | |||||
| "method", r.Method, | "method", r.Method, | ||||
| "path", r.URL.Path, | "path", r.URL.Path, | ||||
| "status", wrap.status, | "status", wrap.status, | ||||
| @@ -23,8 +23,6 @@ func GetToken(ctx context.Context, cfg *config.Config, client *http.Client) (str | |||||
| formData.Set("username", cfg.HTTPUsername) | formData.Set("username", cfg.HTTPUsername) | ||||
| formData.Set("password", cfg.HTTPPassword) | formData.Set("password", cfg.HTTPPassword) | ||||
| formData.Set("audience", cfg.HTTPAudience) | formData.Set("audience", cfg.HTTPAudience) | ||||
| fmt.Printf("formData: %+v\n", formData) | |||||
| fmt.Printf("cfg.APIAuthURL: %+v\n", cfg.APIAuthURL) | |||||
| req, err := http.NewRequest("POST", fmt.Sprintf("%s/realms/API.Server.local/protocol/openid-connect/token", cfg.APIAuthURL), strings.NewReader(formData.Encode())) | req, err := http.NewRequest("POST", fmt.Sprintf("%s/realms/API.Server.local/protocol/openid-connect/token", cfg.APIAuthURL), strings.NewReader(formData.Encode())) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -44,7 +42,5 @@ func GetToken(ctx context.Context, cfg *config.Config, client *http.Client) (str | |||||
| return "", err | return "", err | ||||
| } | } | ||||
| fmt.Printf("token: %s\n", j.Token) | |||||
| return j.Token, nil | return j.Token, nil | ||||
| } | } | ||||
| @@ -8,14 +8,20 @@ import ( | |||||
| // CreateLogger creates a logger writing to both stderr and the given file. | // CreateLogger creates a logger writing to both stderr and the given file. | ||||
| // If the file cannot be opened, returns a logger that writes only to stderr and a no-op cleanup. | // If the file cannot be opened, returns a logger that writes only to stderr and a no-op cleanup. | ||||
| // Callers can check whether logging to file is active if needed. | |||||
| // Log level is controlled by the LOG_LEVEL env var (debug/info/warn/error); defaults to info. | |||||
| func CreateLogger(fname string) (*slog.Logger, func()) { | func CreateLogger(fname string) (*slog.Logger, func()) { | ||||
| lvl := &slog.LevelVar{} | |||||
| if v := os.Getenv("LOG_LEVEL"); v != "" { | |||||
| _ = lvl.UnmarshalText([]byte(v)) | |||||
| } | |||||
| opts := &slog.HandlerOptions{Level: lvl} | |||||
| f, err := os.OpenFile(fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) | f, err := os.OpenFile(fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) | ||||
| if err != nil { | if err != nil { | ||||
| return slog.New(slog.NewJSONHandler(os.Stderr, nil)), func() {} | |||||
| return slog.New(slog.NewJSONHandler(os.Stderr, opts)), func() {} | |||||
| } | } | ||||
| w := io.MultiWriter(os.Stderr, f) | w := io.MultiWriter(os.Stderr, f) | ||||
| logger := slog.New(slog.NewJSONHandler(w, nil)) | |||||
| logger := slog.New(slog.NewJSONHandler(w, opts)) | |||||
| cleanup := func() { f.Close() } | cleanup := func() { f.Close() } | ||||
| return logger, cleanup | return logger, cleanup | ||||
| } | } | ||||
| @@ -82,8 +82,6 @@ func LocationToBeaconService(msg model.HTTPLocation, db *gorm.DB, writer *kafka. | |||||
| return | return | ||||
| } | } | ||||
| fmt.Printf("floor: %d\n", floor.FloorNumber) | |||||
| if err := db.Create(&model.Tracks{ | if err := db.Create(&model.Tracks{ | ||||
| UUID: msg.ID, | UUID: msg.ID, | ||||
| Timestamp: time.Now(), | Timestamp: time.Now(), | ||||
| @@ -114,7 +112,6 @@ func LocationToBeaconService(msg model.HTTPLocation, db *gorm.DB, writer *kafka. | |||||
| } | } | ||||
| func LocationToBeaconServiceAI(msg model.HTTPLocation, db *gorm.DB, writer *kafka.Writer, ctx context.Context) { | func LocationToBeaconServiceAI(msg model.HTTPLocation, db *gorm.DB, writer *kafka.Writer, ctx context.Context) { | ||||
| fmt.Printf("msg: %+v\n", msg) | |||||
| tracker, err := findTracker(msg, db) | tracker, err := findTracker(msg, db) | ||||
| if err != nil { | if err != nil { | ||||
| msg := fmt.Sprintf("Error in finding tracker: %v", err) | msg := fmt.Sprintf("Error in finding tracker: %v", err) | ||||
| @@ -136,8 +133,6 @@ func LocationToBeaconServiceAI(msg model.HTTPLocation, db *gorm.DB, writer *kafk | |||||
| return | return | ||||
| } | } | ||||
| // fmt.Printf("gw: %+v\n", gw) | |||||
| if err := db.Create(&model.Tracks{UUID: tracker.ID, Timestamp: time.Now(), Gateway: gw.ID, GatewayMac: gw.MAC, Tracker: tracker.ID, Floor: gw.Floor, Building: gw.Building, TrackerMac: tracker.MAC, X: msg.X, Y: msg.Y, Z: msg.Z}).Error; err != nil { | if err := db.Create(&model.Tracks{UUID: tracker.ID, Timestamp: time.Now(), Gateway: gw.ID, GatewayMac: gw.MAC, Tracker: tracker.ID, Floor: gw.Floor, Building: gw.Building, TrackerMac: tracker.MAC, X: msg.X, Y: msg.Y, Z: msg.Z}).Error; err != nil { | ||||
| msg := fmt.Sprintf("Error in saving distance for beacon: %v", err) | msg := fmt.Sprintf("Error in saving distance for beacon: %v", err) | ||||
| slog.Error(msg) | slog.Error(msg) | ||||