Skip to content

Commit 5e625c0

Browse files
authored
Merge pull request #8 from wavezync/chore/readme
2 parents 130cab1 + 109beff commit 5e625c0

File tree

3 files changed

+226
-6
lines changed

3 files changed

+226
-6
lines changed

README.md

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,120 @@ Simply create a configuration file to define multiple services and databases to
1414
- Redis
1515
- MSSQL
1616

17-
## Monitoring
17+
- HTTP - Headers and all that
18+
- Postgresql
19+
- MySQL
20+
- MariaDB
21+
- MSSQL
22+
- Redis
23+
24+
## Deployment
25+
26+
27+
Deployment options:
28+
- [Dockerfile](https://github.com/wavezync/pulse-bridge/blob/main/Dockerfile) – Self-hosted container registry or Docker Hub image
29+
- Kubernetes
30+
31+
### 💻 Deploy locally (Build from source)
32+
33+
```bash
34+
git clone https://github.com/wavezync/pulse-bridge.git
35+
cd pulse-bridge
36+
go run .
37+
```
38+
39+
### 🐳 Deploy with Docker
40+
41+
```bash
42+
docker pull ghcr.io/wavezync/pulsebridge:latest
43+
docker run -d -p 8080:8080 ghcr.io/wavezync/pulsebridge:latest
44+
```
45+
46+
Update the [config.yml](https://github.com/wavezync/pulse-bridge/blob/main/config.yml) in the project root to add your services and databases. Then rebuild the binary or Docker image and run it.
47+
48+
### 🚢 Deploy with Kubernetes
1849

50+
There are many ways to deploy Pulse Bridge on Kubernetes. Below is a simple example using a Deployment, Service, and ConfigMap.
51+
52+
```yaml
53+
apiVersion: apps/v1
54+
kind: Deployment
55+
metadata:
56+
name: pulse-bridge
57+
spec:
58+
replicas: 1
59+
selector:
60+
matchLabels:
61+
app: pulse-bridge
62+
template:
63+
metadata:
64+
labels:
65+
app: pulse-bridge
66+
spec:
67+
containers:
68+
- name: pulse-bridge
69+
image: wavezync/pulse-bridge:latest # Replace with your image if needed (recommended)
70+
ports:
71+
- containerPort: 8080
72+
env:
73+
- name: PULSE_BRIDGE_CONFIG
74+
value: "/config/config.yml"
75+
volumeMounts:
76+
- name: config-volume
77+
mountPath: /config
78+
volumes:
79+
- name: config-volume
80+
configMap:
81+
name: pulse-bridge-config
82+
---
83+
apiVersion: v1
84+
kind: Service
85+
metadata:
86+
name: pulse-bridge
87+
spec:
88+
selector:
89+
app: pulse-bridge
90+
ports:
91+
- protocol: TCP
92+
port: 8080
93+
targetPort: 8080
94+
---
95+
apiVersion: v1
96+
kind: ConfigMap
97+
metadata:
98+
name: pulse-bridge-config
99+
data:
100+
config.yml: |
101+
# Paste your Pulse Bridge YAML config here. See the guide below for configuration details.
102+
```
103+
104+
105+
### Environment Configuration
106+
107+
1. .env file:
108+
109+
A .env file is **optional** but can be configured:
110+
111+
```bash
112+
PULSE_BRIDGE_CONFIG=mycustomconfig.yml # Sets the custom configuration file path, defaults to config.yml
113+
HOST=0.0.0.0 # Defaults to 0.0.0.0
114+
PORT=8080 # Defaults to 8080
115+
```
116+
117+
2. CLI arguments:
118+
119+
```bash
120+
pb --config=mycustomconfig.yml --port=8080 --host=0.0.0.0
121+
```
122+
123+
> **Note:** CLI arguments take priority over `.env` file settings.
19124
CLI > .env
20125
21126

22127

23-
## Configuration
128+
## Usage
129+
130+
### Configuring your services
24131

25132
The configuration file is a YAML file where you can define the services and databases you want to monitor.
26133

@@ -101,7 +208,8 @@ monitors:
101208
query: "SELECT 1"
102209
```
103210
104-
## Monitoring
211+
### Monitoring
212+
105213
106214
You can check the status of your service from the pulse bridge API at the routes:
107215

cmd/root.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package cmd
22

33
import (
4+
"fmt"
45
"wavezync/pulse-bridge/cmd/pulsebridge"
56
"wavezync/pulse-bridge/internal/env"
7+
"wavezync/pulse-bridge/internal/version"
68

79
"github.com/rs/zerolog"
810
"github.com/rs/zerolog/log"
@@ -16,10 +18,16 @@ var (
1618
)
1719

1820
var rootCmd = &cobra.Command{
19-
Use: "pulsebridge",
20-
Short: "pulsebridge is a powerful uptime monitoring tool",
21-
Long: `pulsebridge exposes internal service status via HTTP, enabling seamless integration with external monitoring tools like Atlassian Statuspage.`,
21+
Use: "pulsebridge",
22+
Short: "pulsebridge is a powerful uptime monitoring tool",
23+
Long: `pulsebridge exposes internal service status via HTTP, enabling seamless integration with external monitoring tools like Atlassian Statuspage.`,
2224
RunE: func(cmd *cobra.Command, args []string) error {
25+
versionFlag, _ := cmd.Flags().GetBool("version")
26+
if versionFlag {
27+
fmt.Println(version.GetVersionWithBuildInfo())
28+
return nil
29+
}
30+
2331
envConfig := env.Init()
2432

2533
if cmd.Flags().Changed("config") {
@@ -40,6 +48,7 @@ func init() {
4048
rootCmd.PersistentFlags().StringVar(&configPath, "config", "config.yml", "Path to configuration file")
4149
rootCmd.PersistentFlags().StringVar(&host, "host", "0.0.0.0", "Host address to bind the server")
4250
rootCmd.PersistentFlags().IntVar(&port, "port", 8080, "Port to run the server")
51+
rootCmd.PersistentFlags().BoolP("version", "v", false, "Print the version and exit")
4352
}
4453

4554
func Execute() {

internal/version/version.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package version
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
"runtime/debug"
7+
"strings"
8+
)
9+
10+
var (
11+
version string
12+
tag string
13+
commit string
14+
dirty bool
15+
)
16+
17+
func init() {
18+
// Always attempt to get build info from the Go runtime, regardless of build type.
19+
if info, ok := debug.ReadBuildInfo(); ok {
20+
if version == "" {
21+
// If version wasn't set via ldflags, try to get it from VCS info
22+
version = getVersionFromVCS(info)
23+
}
24+
commit = getCommit(info)
25+
dirty = getDirty(info)
26+
}
27+
28+
// Fallback version if nothing else is available
29+
if version == "" {
30+
version = "dev"
31+
}
32+
}
33+
34+
func getVersionFromVCS(info *debug.BuildInfo) string {
35+
for _, setting := range info.Settings {
36+
if setting.Key == "vcs.revision" {
37+
// Use commit hash as version if no proper version is available
38+
if len(setting.Value) >= 7 {
39+
return "dev-" + setting.Value[:7]
40+
}
41+
}
42+
}
43+
return ""
44+
}
45+
46+
func getDirty(info *debug.BuildInfo) bool {
47+
for _, setting := range info.Settings {
48+
if setting.Key == "vcs.modified" {
49+
return setting.Value == "true"
50+
}
51+
}
52+
return false
53+
}
54+
55+
func getCommit(info *debug.BuildInfo) string {
56+
for _, setting := range info.Settings {
57+
if setting.Key == "vcs.revision" {
58+
return setting.Value[:7]
59+
}
60+
}
61+
return ""
62+
}
63+
64+
// GetVersion returns the version of pulsebridge. This should be injected at build time
65+
// using: -ldflags="-X 'wavezync/pulse-bridge/internal/version.version=vX.X.X'".
66+
// If not provided, it will attempt to derive a version from VCS info.
67+
func GetVersion() string {
68+
return version
69+
}
70+
71+
// GetVersionWithBuildInfo returns detailed version information including
72+
// commit hash, dirty status, and Go version. This will work when built
73+
// within a Git checkout.
74+
func GetVersionWithBuildInfo() string {
75+
var parts []string
76+
77+
// Add the main version
78+
parts = append(parts, fmt.Sprintf("Version: %s", version))
79+
80+
// Add build metadata
81+
var buildMetadata []string
82+
if tag != "" {
83+
buildMetadata = append(buildMetadata, tag)
84+
}
85+
if commit != "" {
86+
buildMetadata = append(buildMetadata, commit)
87+
}
88+
if dirty {
89+
buildMetadata = append(buildMetadata, "dirty")
90+
}
91+
92+
if len(buildMetadata) > 0 {
93+
parts = append(parts, fmt.Sprintf("Build: %s", strings.Join(buildMetadata, ".")))
94+
}
95+
96+
// Add Go version
97+
parts = append(parts, fmt.Sprintf("Go: %s", runtime.Version()))
98+
99+
// Add architecture
100+
parts = append(parts, fmt.Sprintf("Platform: %s/%s", runtime.GOOS, runtime.GOARCH))
101+
102+
return strings.Join(parts, "\n")
103+
}

0 commit comments

Comments
 (0)