Skip to content

Commit d803cfe

Browse files
committed
Merge branch 'main' into release
2 parents 62499c8 + 1dbb4ef commit d803cfe

File tree

11 files changed

+1010
-109
lines changed

11 files changed

+1010
-109
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ FROM quay.io/samba.org/samba-server:v0.5
2727
COPY --from=builder /workspace/smbmetrics /bin/smbmetrics
2828

2929
ENTRYPOINT ["/bin/smbmetrics"]
30-
EXPOSE 8080
30+
EXPOSE 9922

README.md

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,73 @@ Samba metrics exporter converts 'smbstatus' output into
66

77
## Build
88

9-
```bash
9+
```console
1010
$ make build
1111

1212
$ make image-build
1313
```
14+
15+
16+
## Query metrics
17+
18+
When running (by privileged user) along-side active SMB server, `smbmetrics`
19+
exports a set of gauge metrics over HTTP via port `9922`. Most metrics become
20+
visible only when active SMB connections exists. Execute the folowing `curl`
21+
command on the same machine where you run `smbmetrics` instance:
22+
23+
```console
24+
$ curl --request GET "http://localhost:9922/metrics"
25+
```
26+
27+
## Exported metrics
28+
29+
| Metric name | Description |
30+
|---------------------------|--------------------------------------------------|
31+
| `smb_metrics_status` | Status and version of running process |
32+
| `smb_sessions_total` | Number of active SMB sessions |
33+
| `smb_tcon_total` | Number of active SMB tree-connections |
34+
| `smb_users_total` | Number of connected users |
35+
| `smb_openfiles_total` | Number of currently open files |
36+
| `smb_openfiles_access_rw` | Open files with `"RW"` access-mask set |
37+
| `smb_share_activity` | Number of remote machines using each share |
38+
| `smb_share_byremote` | Number of shares used by each remote machine |
39+
40+
41+
42+
## Example
43+
44+
The following example is from a setup with 2 shares and 2 users connected and
45+
performing SMB file-system operations from 4 different machines:
46+
47+
```console
48+
$ curl --request GET "http://localhost:9922/metrics"
49+
50+
# HELP smb_metrics_status Current metrics-collector status versions
51+
# TYPE smb_metrics_status gauge
52+
smb_metrics_status{commitid="092fe2bb0",ctdbvers="4.20.0-103",sambaimage="",sambavers="4.20.0-103",version="v0.2-28-g092fe2b"} 1
53+
# HELP smb_sessions_total Number of currently active SMB sessions
54+
# TYPE smb_sessions_total gauge
55+
smb_sessions_total 8
56+
# HELP smb_tcon_total Number of currently active SMB tree-connections
57+
# TYPE smb_tcon_total gauge
58+
smb_tcon_total 8
59+
# HELP smb_users_total Number of currently active SMB users
60+
# TYPE smb_users_total gauge
61+
smb_users_total 2
62+
# HELP smb_openfiles_total Number of currently open files
63+
# TYPE smb_openfiles_total gauge
64+
smb_openfiles_total 5
65+
# HELP smb_openfiles_access_rw Number of open files with read-write access mode
66+
# TYPE smb_openfiles_access_rw gauge
67+
smb_openfiles_access_rw 4
68+
# HELP smb_share_activity Number of remote machines currently using a share
69+
# TYPE smb_share_activity gauge
70+
smb_share_activity{service="smbshare1"} 4
71+
smb_share_activity{service="smbshare2"} 2
72+
# HELP smb_share_for_remote Number of shares served for remote machine
73+
# TYPE smb_share_for_remote gauge
74+
smb_share_byremote{machine="192.168.122.71"} 2
75+
smb_share_byremote{machine="192.168.122.72"} 1
76+
smb_share_byremote{machine="192.168.122.73"} 2
77+
smb_share_byremote{machine="192.168.122.74"} 1
78+
```

cmd/main.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
goruntime "runtime"
88

9+
"github.com/spf13/pflag"
910
"sigs.k8s.io/controller-runtime/pkg/log/zap"
1011

1112
"github.com/samba-in-kubernetes/smbmetrics/internal/metrics"
@@ -23,6 +24,11 @@ func init() {
2324
}
2425

2526
func main() {
27+
var port int
28+
pflag.IntVar(&port, "port", metrics.DefaultMetricsPort,
29+
"Prometheus metrics-exporter port number")
30+
pflag.Parse()
31+
2632
log := zap.New(zap.UseDevMode(true))
2733
log.Info("Initializing smbmetrics",
2834
"ProgramName", os.Args[0],
@@ -48,7 +54,7 @@ func main() {
4854
}
4955
log.Info("Located smbstatus", "path", loc, "version", ver)
5056

51-
err = metrics.RunSmbMetricsExporter(log)
57+
err = metrics.RunSmbMetricsExporter(log, port)
5258
if err != nil {
5359
os.Exit(1)
5460
}

docs/release-process.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# samba-container Release Process
2+
3+
## Preparation
4+
5+
The smbmetrics project has a dedicated branch, called `release`, for release
6+
versions. This is done to update files, in particular the Dockerfile, that
7+
control dependencies and versioning. Tags are applied directly to this branch
8+
and only this branch.
9+
10+
11+
### Tagging
12+
13+
Prior to tagging, we must update the `release` branch to "contain" all the
14+
latest changes from the `main` branch. We do this by merging `main` into
15+
`release`.
16+
Example:
17+
18+
```
19+
git checkout main
20+
git pull --ff-only
21+
git checkout release
22+
git pull --ff-only
23+
git merge main
24+
# resolve any conflicts
25+
```
26+
27+
Now we need to "pin" the appropriate version of the samba-server container
28+
dependency. Edit `Dockerfile` and change the tag part of the "FROM" line with
29+
the `quay.io/samba.org/samba-server` image repository to use the latest
30+
released samba-server tag.
31+
32+
At this point, an optional but recommended step is to do a test build before
33+
tagging. Run `make image-build`.
34+
35+
If you are happy with the content of the `release` branch, tag it. Example:
36+
37+
```
38+
git checkout release
39+
git tag -a -m 'Release v0.5' v0.5
40+
```
41+
42+
This creates an annotated tag. Release tags must be annotated tags.
43+
44+
### Build
45+
46+
Using the tagged `release` branch, the container images for release will be
47+
built. It is very important to ensure that base images are up-to-date.
48+
It is very important to ensure that you perform the next set of steps with
49+
clean new builds and do not use cached images. To accomplish both tasks it
50+
is recommended to purge your local container engine of cached images
51+
(Example: `podman image rm --all`). You should have no images named like
52+
`quay.io/samba.org` in your local cache.
53+
54+
Build the images from scratch. Example:
55+
```
56+
make image-build
57+
```
58+
59+
For the image that was just built, apply a temporary pre-release tag
60+
to it. Example:
61+
```
62+
podman tag quay.io/samba.org/samba-metrics:{latest,v0.5pre1}
63+
```
64+
65+
Log into quay.io. Push the images to quay.io using the temporary tag. Example:
66+
```
67+
podman push quay.io/samba.org/samba-metrics:{latest,v0.5pre1}
68+
```
69+
70+
Wait for the security scan to complete. There shouldn't be any issues if you
71+
properly updated the base images before building. If there are issues and you
72+
are sure you used the newest base images, check the base images on quay.io and
73+
make sure that the number of issues are identical. The security scan can take
74+
some time, while it runs you may want to do other things.
75+
76+
77+
## GitHub Release
78+
79+
When you are satisfied that the tagged version is suitable for release, you
80+
can push the tag to the public repo:
81+
```
82+
git push --follow-tags
83+
```
84+
85+
Draft a new set of release notes. Select the recently pushed tag. Start with
86+
the auto-generated release notes from GitHub (activate the `Generate release
87+
notes` button/link). Add an introductory section (see previous notes for an
88+
example). Add a "Highlights" section if there are any notable features or fixes
89+
in the release. The Highlights section can be skipped if the content of the
90+
release is unremarkable (e.g. few changes occurred since the previous release).
91+
92+
Because this is a container based release we do not provide any build artifacts
93+
on GitHub (beyond the sources automatically provided there). Instead we add
94+
a Downloads section that notes the exact tags and digests that the images can
95+
be found at on quay.io.
96+
97+
Use the following partial snippet as an example:
98+
```
99+
## Download
100+
101+
Images built for this release can be obtained from the quay.io image registry.
102+
103+
* By tag: quay.io/samba.org/samba-metrics:v0.5
104+
* By digest: quay.io/samba.org/samba-metrics@sha256:09c867343af39b237230f94a734eacc8313f2330c7d934994522ced46b740715
105+
```
106+
... using the image that was pushed earlier
107+
108+
The tag is pretty obvious - it should match the image tag (minus any pre-release
109+
marker). You can get the digest from the tag using the quay.io UI (do not use
110+
any local digest hashes). Click on the SHA256 link and then copy the full
111+
manifest hash using the UI widget that appears.
112+
113+
Perform a final round of reviews, as needed, for the release notes and then
114+
publish the release.
115+
116+
Once the release notes are drafted and then either immediately before or after
117+
publishing them, use the quay.io UI to copy each pre-release tag to the "latest"
118+
tag and a final "vX.Y" tag. Delete the temporary pre-release tags using the
119+
quay.io UI as they are no longer needed.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.16
55
require (
66
github.com/go-logr/logr v0.4.0
77
github.com/prometheus/client_golang v1.11.1
8+
github.com/spf13/pflag v1.0.5
89
github.com/stretchr/testify v1.7.0
910
k8s.io/api v0.22.2
1011
k8s.io/apimachinery v0.22.2

internal/metrics/collectors.go

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ var (
1212

1313
func (sme *smbMetricsExporter) register() error {
1414
cols := []prometheus.Collector{
15-
sme.newSmbVersionsCollector(),
16-
sme.newSmbSharesCollector(),
17-
sme.newSmbLocksCollector(),
15+
sme.newSMBVersionsCollector(),
16+
sme.newSMBActivityCollector(),
17+
sme.newSMBSharesCollector(),
1818
}
1919
for _, c := range cols {
2020
if err := sme.reg.Register(c); err != nil {
@@ -60,7 +60,7 @@ func (col *smbVersionsCollector) Collect(ch chan<- prometheus.Metric) {
6060
)
6161
}
6262

63-
func (sme *smbMetricsExporter) newSmbVersionsCollector() prometheus.Collector {
63+
func (sme *smbMetricsExporter) newSMBVersionsCollector() prometheus.Collector {
6464
col := &smbVersionsCollector{}
6565
col.sme = sme
6666
col.clnt, _ = newKClient()
@@ -79,59 +79,107 @@ func (sme *smbMetricsExporter) newSmbVersionsCollector() prometheus.Collector {
7979
return col
8080
}
8181

82-
type smbSharesCollector struct {
82+
type smbActivityCollector struct {
8383
smbCollector
8484
}
8585

86-
func (col *smbSharesCollector) Collect(ch chan<- prometheus.Metric) {
87-
sharesTotal := 0
88-
sharesMap, _ := SMBStatusSharesByMachine()
89-
for machine, share := range sharesMap {
90-
sharesCount := len(share)
91-
ch <- prometheus.MustNewConstMetric(col.dsc[0],
92-
prometheus.GaugeValue, float64(sharesCount), machine)
93-
sharesTotal += sharesCount
86+
func (col *smbActivityCollector) Collect(ch chan<- prometheus.Metric) {
87+
totalSessions := 0
88+
totalTreeCons := 0
89+
totalConnectedUsers := 0
90+
totalOpenFiles := 0
91+
totalOpenFilesAccessRW := 0
92+
smbInfo, err := NewUpdatedSMBInfo()
93+
if err == nil {
94+
totalSessions = smbInfo.TotalSessions()
95+
totalTreeCons = smbInfo.TotalTreeCons()
96+
totalConnectedUsers = smbInfo.TotalConnectedUsers()
97+
totalOpenFiles = smbInfo.TotalOpenFiles()
98+
totalOpenFilesAccessRW = smbInfo.TotalOpenFilesAccessRW()
9499
}
100+
ch <- prometheus.MustNewConstMetric(col.dsc[0],
101+
prometheus.GaugeValue, float64(totalSessions))
95102

96103
ch <- prometheus.MustNewConstMetric(col.dsc[1],
97-
prometheus.GaugeValue, float64(sharesTotal))
104+
prometheus.GaugeValue, float64(totalTreeCons))
105+
106+
ch <- prometheus.MustNewConstMetric(col.dsc[2],
107+
prometheus.GaugeValue, float64(totalConnectedUsers))
108+
109+
ch <- prometheus.MustNewConstMetric(col.dsc[3],
110+
prometheus.GaugeValue, float64(totalOpenFiles))
111+
112+
ch <- prometheus.MustNewConstMetric(col.dsc[4],
113+
prometheus.GaugeValue, float64(totalOpenFilesAccessRW))
98114
}
99115

100-
func (sme *smbMetricsExporter) newSmbSharesCollector() prometheus.Collector {
101-
col := &smbSharesCollector{}
116+
func (sme *smbMetricsExporter) newSMBActivityCollector() prometheus.Collector {
117+
col := &smbActivityCollector{}
102118
col.sme = sme
103119
col.dsc = []*prometheus.Desc{
104120
prometheus.NewDesc(
105-
collectorName("shares", "machine"),
106-
"Number of shares by host-machine ip",
107-
[]string{"machine"}, nil),
121+
collectorName("sessions", "total"),
122+
"Number of currently active SMB sessions",
123+
[]string{}, nil),
124+
125+
prometheus.NewDesc(
126+
collectorName("tcon", "total"),
127+
"Number of currently active SMB tree-connections",
128+
[]string{}, nil),
129+
130+
prometheus.NewDesc(
131+
collectorName("users", "total"),
132+
"Number of currently active SMB users",
133+
[]string{}, nil),
134+
135+
prometheus.NewDesc(
136+
collectorName("openfiles", "total"),
137+
"Number of currently open files",
138+
[]string{}, nil),
108139

109140
prometheus.NewDesc(
110-
collectorName("shares", "total"),
111-
"Total number of active shares",
141+
collectorName("openfiles", "access_rw"),
142+
"Number of open files with read-write access mode",
112143
[]string{}, nil),
113144
}
114145
return col
115146
}
116147

117-
type smbLocksCollector struct {
148+
type smbSharesCollector struct {
118149
smbCollector
119150
}
120151

121-
func (col *smbLocksCollector) Collect(ch chan<- prometheus.Metric) {
122-
locks, _ := RunSMBStatusLocks()
123-
ch <- prometheus.MustNewConstMetric(col.dsc[0],
124-
prometheus.GaugeValue, float64(len(locks)))
152+
func (col *smbSharesCollector) Collect(ch chan<- prometheus.Metric) {
153+
smbInfo, _ := NewUpdatedSMBInfo()
154+
serviceToMachine := smbInfo.MapServiceToMachines()
155+
for service, machines := range serviceToMachine {
156+
ch <- prometheus.MustNewConstMetric(col.dsc[0],
157+
prometheus.GaugeValue,
158+
float64(len(machines)),
159+
service)
160+
}
161+
machineToServices := smbInfo.MapMachineToServies()
162+
for machine, services := range machineToServices {
163+
ch <- prometheus.MustNewConstMetric(col.dsc[1],
164+
prometheus.GaugeValue,
165+
float64(len(services)),
166+
machine)
167+
}
125168
}
126169

127-
func (sme *smbMetricsExporter) newSmbLocksCollector() prometheus.Collector {
128-
col := &smbLocksCollector{}
170+
func (sme *smbMetricsExporter) newSMBSharesCollector() prometheus.Collector {
171+
col := &smbSharesCollector{}
129172
col.sme = sme
130173
col.dsc = []*prometheus.Desc{
131174
prometheus.NewDesc(
132-
collectorName("locks", "total"),
133-
"Total number of active locks",
134-
[]string{}, nil),
175+
collectorName("share", "activity"),
176+
"Number of remote machines currently using a share",
177+
[]string{"service"}, nil),
178+
179+
prometheus.NewDesc(
180+
collectorName("share", "byremote"),
181+
"Number of shares served for remote machine",
182+
[]string{"machine"}, nil),
135183
}
136184
return col
137185
}

0 commit comments

Comments
 (0)