Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DI with Uber Fx #4

Merged
merged 5 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ tmp_dir = "tmp"
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html", "yml"]
kill_delay = "0s"
kill_delay = "1s"
log = "build-errors.log"
send_interrupt = false
send_interrupt = true
stop_on_error = true

[color]
Expand All @@ -33,4 +33,4 @@ tmp_dir = "tmp"
clean_on_exit = true

[screen]
clear_on_rebuild = false
clear_on_rebuild = true
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CI

on:
push:
pull_request:

jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
# step 1: checkout repository code
- name: Checkout code into workspace directory
uses: actions/checkout@v4

# step 2: set up go
- name: Set up Go 1.21
uses: actions/setup-go@v4
with:
go-version: ">=1.21"

# step 3: install dependencies
- name: Install all Go dependencies
run: go mod download

# step 4: run test
- name: Run coverage
run: go test -race -coverprofile=coverage.out -covermode=atomic ./...
19 changes: 17 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ ifeq ($(OS),Windows_NT)
extension = .exe
endif

init:
run:
go run ./cmd/$(project_name)/main.go

init-dev:
go mod download \
&& go install github.com/cosmtrek/air@latest

init: init-dev
go mod download \
&& go install github.com/pressly/goose/v3/cmd/goose@latest \
&& go install github.com/cosmtrek/air@latest

air:
Expand All @@ -30,4 +36,13 @@ api-docs:
view-docs:
php -S 127.0.0.1:8080 -t ./api

docker-build:
docker build -f build/package/Dockerfile -t $(image_name) --build-arg APP=$(project_name) .

docker:
docker-compose -f deployments/docker-compose/docker-compose.yml up --build

docker-dev:
docker-compose -f deployments/docker-compose/docker-compose.dev.yml up --build

.PHONY: init air db-upgrade db-upgrade-raw test api-docs view-docs
2 changes: 1 addition & 1 deletion build/package/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Building the binary of the App
FROM golang:1.18-alpine AS build
FROM golang:1.21-alpine AS build

ARG APP
WORKDIR /go/src
Expand Down
6 changes: 1 addition & 5 deletions cmd/service-monitor-tgbot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,9 @@
package main

import (
"log"

"github.com/capcom6/service-monitor-tgbot/internal/bot"
)

func main() {
if err := bot.Run(); err != nil {
log.Fatalln("An error occured", err)
}
bot.Run()
}
16 changes: 16 additions & 0 deletions deployments/docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: '3'
services:
bot:
image: capcom6/service-monitor-tgbot
build:
context: ../..
dockerfile: ./build/package/Dockerfile
args:
- APP=service-monitor-tgbot
env_file:
- ../../.env
environment:
- CONFIG_PATH=config.yml
stop_signal: SIGINT
volumes:
- ../../configs/config.yml:/app/config.yml:ro
15 changes: 9 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
module github.com/capcom6/service-monitor-tgbot

go 1.18
go 1.21.3

require (
github.com/go-redis/redis/v9 v9.0.0-rc.2
github.com/capcom6/go-infra-fx v0.0.0-20231222163248-fa41dba8d031
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/joho/godotenv v1.4.0
github.com/kelseyhightower/envconfig v1.4.0
go.uber.org/fx v1.20.1
go.uber.org/zap v1.26.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
go.uber.org/dig v1.17.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sys v0.15.0 // indirect
)
40 changes: 23 additions & 17 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/capcom6/go-infra-fx v0.0.0-20231222163248-fa41dba8d031 h1:d6YzZW6TU0MgpPcWaPYSpOnQw45gJBWNFqf+0rz2gVg=
github.com/capcom6/go-infra-fx v0.0.0-20231222163248-fa41dba8d031/go.mod h1:3wSBR0bVZ/fwWYo05PSoMLO4nS6mhmK0kz5MFFl1PP4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/go-redis/redis/v9 v9.0.0-rc.2 h1:IN1eI8AvJJeWHjMW/hlFAv2sAfvTun2DVksDDJ3a6a0=
github.com/go-redis/redis/v9 v9.0.0-rc.2/go.mod h1:cgBknjwcBJa2prbnuHH/4k/Mlj4r0pWNV2HBanHujfY=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI=
go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU=
go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk=
go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
130 changes: 74 additions & 56 deletions internal/bot/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,92 @@ package bot

import (
"context"
"fmt"
"math/rand"
"os"
"os/signal"
"time"
"sync"

"github.com/capcom6/go-infra-fx/logger"
"github.com/capcom6/service-monitor-tgbot/internal/config"
"github.com/capcom6/service-monitor-tgbot/internal/infrastructure"
"github.com/capcom6/service-monitor-tgbot/internal/monitor"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/capcom6/service-monitor-tgbot/internal/storage"
"go.uber.org/fx"
"go.uber.org/fx/fxevent"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

func Run() error {
rand.Seed(time.Now().UnixNano())

cfg := config.GetConfig()
ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)

messages := NewMessages(cfg.Telegram.Messages)
tg := infrastructure.NewTelegramBot(cfg.Telegram)
tgapi, err := tg.Api()
if err != nil {
return fmt.Errorf("can't init Telegram Api client: %w", err)
}

module := monitor.NewMonitorModule(cfg.Services)
ch, err := module.Monitor(ctx)
if err != nil {
return err
}

log.Println("Started")

for v := range ch {
log.Printf("%+v\n", v)
var Module = fx.Module(
"bot",
logger.Module,
config.Module,
infrastructure.Module,
monitor.Module,
storage.Module,
fx.Provide(NewMessages),
)

msg := tgbotapi.NewMessage(cfg.Telegram.ChatID, "")
msg.ParseMode = tgbotapi.ModeMarkdownV2
if v.State == monitor.ServiceOffline {
// msg.Text = "❌ " + tgbotapi.EscapeText(msg.ParseMode, v.Name) + " is *offline*: " + tgbotapi.EscapeText(msg.ParseMode, v.Error.Error())
context := OfflineContext{
OnlineContext: OnlineContext{
Name: tgbotapi.EscapeText(msg.ParseMode, v.Name),
func Run() {
fx.New(
Module,
fx.WithLogger(func(logger *zap.Logger) fxevent.Logger {
logOption := fxevent.ZapLogger{Logger: logger}
logOption.UseLogLevel(zapcore.DebugLevel)
return &logOption
}),
fx.Invoke(func(lc fx.Lifecycle, logger *zap.Logger, bot *infrastructure.TelegramBot, monitorMod *monitor.MonitorModule, messages *Messages) error {
ctx, cancel := context.WithCancel(context.Background())
wg := &sync.WaitGroup{}
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
logger.Info("Started")
return nil
},
Error: tgbotapi.EscapeText(msg.ParseMode, v.Error.Error()),
}
msg.Text, err = messages.Render(TemplateOffline, context)
} else {
// msg.Text = "✅ " + tgbotapi.EscapeText(msg.ParseMode, v.Name) + " is *online*"
context := OnlineContext{
Name: tgbotapi.EscapeText(msg.ParseMode, v.Name),
OnStop: func(ctx context.Context) error {
cancel()
wg.Wait()
logger.Info("Stopped")
return nil
},
})

ch, err := monitorMod.Monitor(ctx)
if err != nil {
return err
}
msg.Text, err = messages.Render(TemplateOnline, context)
}

if err != nil {
errorLog.Println(err)
continue
}
wg.Add(1)
go func() {
defer wg.Done()
for v := range ch {
logger.Debug("probe", zap.String("name", v.Name), zap.String("state", string(v.State)), zap.Error(v.Error))

if _, err := tgapi.Send(msg); err != nil {
errorLog.Println(err)
}
}
msg := ""
if v.State == monitor.ServiceOffline {
context := OfflineContext{
OnlineContext: OnlineContext{
Name: bot.EscapeText(v.Name),
},
Error: bot.EscapeText(v.Error.Error()),
}
msg, err = messages.Render(TemplateOffline, context)
} else {
context := OnlineContext{
Name: bot.EscapeText(v.Name),
}
msg, err = messages.Render(TemplateOnline, context)
}

<-ctx.Done()
if err != nil {
logger.Error("can't render template", zap.Error(err))
continue
}

log.Println("Done")
if err := bot.SendMessage(msg); err != nil {
logger.Error("can't send message", zap.Error(err))
}
}
}()

return nil
return nil
}),
).Run()
}
16 changes: 0 additions & 16 deletions internal/bot/log.go

This file was deleted.

Loading
Loading