Skip to content

Commit 2536329

Browse files
Introduce options to control memory usage, and general third-party updates (#55)
- add more control over memory usage - update various dependencies --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent fed279d commit 2536329

File tree

8 files changed

+128
-58
lines changed

8 files changed

+128
-58
lines changed

Diff for: Dockerfile

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
ARG BASE_IMAGE
22
FROM ${BASE_IMAGE} AS build
33

4-
RUN microdnf install golang-1.20.10
4+
RUN microdnf install wget gzip gcc && \
5+
wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && \
6+
rm -rf /usr/local/go && \
7+
tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && \
8+
rm go1.21.6.linux-amd64.tar.gz
9+
10+
ENV PATH $PATH:/usr/local/go/bin
511

612
WORKDIR /go/src/oracledb_exporter
713
COPY . .
@@ -10,7 +16,7 @@ RUN go get -d -v
1016
ARG VERSION
1117
ENV VERSION ${VERSION:-1.0.0}
1218

13-
RUN GOOS=linux GOARCH=amd64 go build -v -ldflags "-X main.Version=${VERSION} -s -w"
19+
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -v -ldflags "-X main.Version=${VERSION} -s -w"
1420

1521
FROM ${BASE_IMAGE} as exporter
1622
LABEL org.opencontainers.image.authors="Oracle America, Inc."

Diff for: Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ OS_TYPE ?= $(shell uname -s | tr '[:upper:]' '[:lower:]')
33
ARCH_TYPE ?= $(subst x86_64,amd64,$(patsubst i%86,386,$(ARCH)))
44
GOOS ?= $(shell go env GOOS)
55
GOARCH ?= $(shell go env GOARCH)
6-
VERSION ?= 1.1.1
6+
VERSION ?= 1.2.0
77
LDFLAGS := -X main.Version=$(VERSION)
88
GOFLAGS := -ldflags "$(LDFLAGS) -s -w"
99
BUILD_ARGS = --build-arg VERSION=$(VERSION)

Diff for: README.md

+23-4
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,21 @@ Contributions are welcome - please see [contributing](CONTRIBUTING.md).
2020
- [Standalone binary](#standalone-binary)
2121
- [Using OCI Vault](#using-oci-vault)
2222
- [Custom metrics](#custom-metrics)
23+
- [Controlling memory usage](#controlling-memory-usage)
2324
- [Grafana dashboards](#grafana-dashboards)
2425
- [Monitoring Transactional Event Queues](#monitoring-transactional-event-queues)
2526
- [Developer notes](#developer-notes)
2627

2728
## Release Notes
2829

30+
### Version 1.2.0, January 17, 2024
31+
32+
This release includes the following changes:
33+
34+
- Introduced a new feature to periodically restart the process if requested.
35+
- Introduced a new feature to periodically attempt to free OS memory if requested.
36+
- Updated some third-party dependencies.
37+
2938
### Version 1.1.1, November 28, 2023
3039

3140
This release just updates some third-party dependencies.
@@ -64,7 +73,6 @@ We always welcome input on features you would like to see supported. Please ope
6473
Currently, we plan to address the following key features:
6574

6675
- Implement multiple database support - allow the exporter to publish metrics for multiple database instances,
67-
- Implement vault support - allow the exporter to obtain database connection information from a secure vault,
6876
- Implement connection storm protection - prevent the exporter from repeatedly connecting when the credentials fail, to prevent a storm of connections causing accounts to be locked across a large number of databases,
6977
- Provide the option to have the Oracle client outside of the container image, e.g., on a shared volume,
7078
- Implement the ability to update the configuration dynamically, i.e., without a restart,
@@ -188,7 +196,7 @@ docker run -it --rm \
188196
-e DB_PASSWORD=Welcome12345 \
189197
-e DB_CONNECT_STRING=free23c:1521/freepdb \
190198
-p 9161:9161 \
191-
container-registry.oracle.com/database/observability-exporter:1.1.1
199+
container-registry.oracle.com/database/observability-exporter:1.2.0
192200
```
193201

194202
##### Using a wallet
@@ -204,6 +212,7 @@ Now, you provide the connection details using these variables:
204212
- `DB_USERNAME` is the database username, e.g., `pdbadmin`
205213
- `DB_PASSWORD` is the password for that user, e.g., `Welcome12345`
206214
- `DB_CONNECT_STRING` is the connection string, e.g., `devdb_tp?TNS_ADMIN=/wallet`
215+
- `ORACLE_HOME` is the location of the Oracle Instant Client, i.e., `/lib/oracle/21/client64/lib`. If you built your own container image, the path may be different.
207216

208217
To run the exporter in a container and expose the port, use a command like this, with the appropriate values for the environment variables, and mounting your `wallet` directory as `/wallet` in the container to provide access to the wallet:
209218

@@ -214,7 +223,7 @@ docker run -it --rm \
214223
-e DB_CONNECT_STRING=devdb_tp \
215224
-v ./wallet:/wallet \
216225
-p 9161:9161 \
217-
container-registry.oracle.com/database/observability-exporter:1.1.1
226+
container-registry.oracle.com/database/observability-exporter:1.2.0
218227
```
219228

220229

@@ -477,11 +486,21 @@ An exmaple of [custom metrics for Transacational Event Queues](./custom-metrics-
477486
If you run the exporter as a container image and want to include your custom metrics in the image itself, you can use the following example `Dockerfile` to create a new image:
478487

479488
```Dockerfile
480-
FROM container-registry.oracle.com/database/observability-exporter:1.1.1
489+
FROM container-registry.oracle.com/database/observability-exporter:1.2.0
481490
COPY custom-metrics.toml /
482491
ENTRYPOINT ["/oracledb_exporter", "--custom.metrics", "/custom-metrics.toml"]
483492
```
484493

494+
## Controlling memory usage
495+
496+
If you are running in an environment with limited memory, or you are running a large number of exporters, you may want to control the exporter's usage of memory.
497+
498+
Under normal circumstances, the exporter process will retain OS memory that was used by the Go garbage collector but is no longer needed, in case it may be needed again in the future, unless the host OS is under memory pressure. The result of this behavior (which is the normal behavior of the Go runtime) is that the resident set size will not decrease until the host OS memory is almost all used. Under most circumstances, this will not cause any issues, but if you are in an environment where you need to conserve memory, the following options are provided:
499+
500+
- You may set the `FREE_INTERVAL` environment variable to a Go [duration string](https://pkg.go.dev/maze.io/x/duration), e.g., `60s` and run the exporter in debug mode by setting the `GODEBUG` environment variable to a value including `madvdontneed=1`, e.g., `GODEBUG=gctrace=1,madvdontneed=1`. The exporter will call the [FreeOSMemory()](https://pkg.go.dev/runtime/debug#FreeOSMemory) at the specified interval. This tells the Go runtime to attempt to release memory which is no longer needed. Please note that this does not guarantee that the memory will be released to the OS, but over time you should see the RSS shrink sooner than without these settings.
501+
- You may set the `RESTART_INTERVAL` environment variable to a Go [duration string](https://pkg.go.dev/maze.io/x/duration), e.g., `10m`. The exporter will restart its own process at the specified iterval (by calling the OS `exec` syscall). As no new process is created, the process identifier (PID) does not change, but the machine code, data, heap, and stack of the process are replaced by those of the new program (source: [Wikipedia](https://en.wikipedia.org/wiki/Exec_(system_call))). This has the side effect of freeing the resident set, so that it will return to its original size.
502+
- In addition to these, you may also set `GOMAXPROCS`, `GOGC`, and `GOMEMLIMIT` (see [documentation](https://pkg.go.dev/runtime#hdr-Environment_Variables)) to further limit the amount of resources that the Go runtime may use.
503+
485504
## Grafana dashboards
486505

487506
A sample Grafana dashboard definition is provided [in this directory](/docker-compose/grafana/dashboards). You can import this into your Grafana instance, and set it to use the Prometheus datasource that you have defined for the Prometheus instance that is collecting metrics from the exporter.

Diff for: collector/collector.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
260260
}(time.Now())
261261

262262
if err = e.db.Ping(); err != nil {
263+
level.Debug(e.logger).Log("msg", "error = "+err.Error())
263264
if strings.Contains(err.Error(), "sql: database is closed") {
264265
level.Info(e.logger).Log("msg", "Reconnecting to DB")
265266
err = e.connect()
@@ -270,7 +271,7 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
270271
}
271272

272273
if err = e.db.Ping(); err != nil {
273-
level.Error(e.logger).Log("msg", "Error pinging oracle:",
274+
level.Error(e.logger).Log("msg", "Error pinging oracle",
274275
"error", err)
275276
e.up.Set(0)
276277
return
@@ -347,16 +348,18 @@ func (e *Exporter) connect() error {
347348
var P godror.ConnectionParams
348349
P.Username, P.Password, P.ConnectString = e.user, godror.NewPassword(e.password), e.connectString
349350

351+
level.Debug(e.logger).Log("msg", "connection properties: "+fmt.Sprint(P))
352+
350353
db := sql.OpenDB(godror.NewConnector(P))
351354
// if err != nil {
352355
// level.Error(e.logger).Log("Error while connecting to", e.dsn)
353356
// return err
354357
// }
355-
level.Debug(e.logger).Log("msg", "set max idle connections to "+strconv.Itoa(e.config.MaxIdleConns))
356-
db.SetMaxIdleConns(e.config.MaxIdleConns)
357-
level.Debug(e.logger).Log("msg", "set max open connections to "+strconv.Itoa(e.config.MaxOpenConns))
358-
db.SetMaxOpenConns(e.config.MaxOpenConns)
359-
level.Debug(e.logger).Log("msg", "Successfully connected to "+maskDsn(e.connectString))
358+
level.Debug(e.logger).Log("msg", "disable go connection pooling, to allow use of oracle's instead")
359+
db.SetMaxIdleConns(0)
360+
db.SetMaxOpenConns(0)
361+
db.SetConnMaxLifetime(0)
362+
level.Debug(e.logger).Log("msg", "Successfully configured connection to "+maskDsn(e.connectString))
360363
e.db = db
361364
return nil
362365
}

Diff for: docker-compose/compose.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ services:
4343
start_period: 30s
4444

4545
exporter:
46-
image: container-registry.oracle.com/database/observability-exporter:1.1.1
46+
image: container-registry.oracle.com/database/observability-exporter:1.2.0
4747
container_name: exporter
4848
ports:
4949
- 9161:9161

Diff for: go.mod

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
module github.com/oracle/oracle-db-appdev-monitoring
22

3-
go 1.20
3+
go 1.21
4+
5+
toolchain go1.21.4
46

57
require (
68
github.com/BurntSushi/toml v1.3.2
79
github.com/alecthomas/kingpin/v2 v2.4.0
810
github.com/go-kit/log v0.2.1
9-
github.com/godror/godror v0.39.3
11+
github.com/godror/godror v0.41.0
1012
github.com/oracle/oci-go-sdk/v65 v65.53.0
11-
github.com/prometheus/client_golang v1.17.0
13+
github.com/prometheus/client_golang v1.18.0
1214
github.com/prometheus/common v0.45.0
13-
github.com/prometheus/exporter-toolkit v0.10.0
15+
github.com/prometheus/exporter-toolkit v0.11.0
1416
)
1517

1618
require (
@@ -23,20 +25,19 @@ require (
2325
github.com/gofrs/flock v0.8.1 // indirect
2426
github.com/golang/protobuf v1.5.3 // indirect
2527
github.com/jpillora/backoff v1.0.0 // indirect
26-
github.com/kr/text v0.2.0 // indirect
2728
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
2829
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
29-
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
30-
github.com/prometheus/procfs v0.11.1 // indirect
30+
github.com/prometheus/client_model v0.5.0 // indirect
31+
github.com/prometheus/procfs v0.12.0 // indirect
3132
github.com/sony/gobreaker v0.5.0 // indirect
3233
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
33-
golang.org/x/crypto v0.14.0 // indirect
34+
golang.org/x/crypto v0.17.0 // indirect
3435
golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect
3536
golang.org/x/net v0.17.0 // indirect
3637
golang.org/x/oauth2 v0.12.0 // indirect
37-
golang.org/x/sync v0.3.0 // indirect
38-
golang.org/x/sys v0.13.0 // indirect
39-
golang.org/x/text v0.13.0 // indirect
38+
golang.org/x/sync v0.5.0 // indirect
39+
golang.org/x/sys v0.15.0 // indirect
40+
golang.org/x/text v0.14.0 // indirect
4041
google.golang.org/appengine v1.6.7 // indirect
4142
google.golang.org/protobuf v1.31.0 // indirect
4243
gopkg.in/yaml.v2 v2.4.0 // indirect

0 commit comments

Comments
 (0)