Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 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
10 changes: 8 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
ARG BASE_IMAGE
FROM ${BASE_IMAGE} AS build

RUN microdnf install golang-1.20.10
RUN microdnf install wget gzip gcc && \
wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && \
rm go1.21.6.linux-amd64.tar.gz

ENV PATH $PATH:/usr/local/go/bin

WORKDIR /go/src/oracledb_exporter
COPY . .
Expand All @@ -10,7 +16,7 @@ RUN go get -d -v
ARG VERSION
ENV VERSION ${VERSION:-1.0.0}

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

FROM ${BASE_IMAGE} as exporter
LABEL org.opencontainers.image.authors="Oracle America, Inc."
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ OS_TYPE ?= $(shell uname -s | tr '[:upper:]' '[:lower:]')
ARCH_TYPE ?= $(subst x86_64,amd64,$(patsubst i%86,386,$(ARCH)))
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
VERSION ?= 1.1.1
VERSION ?= 1.1.2
LDFLAGS := -X main.Version=$(VERSION)
GOFLAGS := -ldflags "$(LDFLAGS) -s -w"
BUILD_ARGS = --build-arg VERSION=$(VERSION)
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ Contributions are welcome - please see [contributing](CONTRIBUTING.md).
- [Standalone binary](#standalone-binary)
- [Using OCI Vault](#using-oci-vault)
- [Custom metrics](#custom-metrics)
- [Controlling memory usage](#controlling-memory-usage)
- [Grafana dashboards](#grafana-dashboards)
- [Monitoring Transactional Event Queues](#monitoring-transactional-event-queues)
- [Developer notes](#developer-notes)

## Release Notes

### Version 1.1.2, January 16, 2024

This release includes the following changes:

- Introduced a new feature to periodically restart the process if requested.
- Introduced a new feature to periodically attempt to free OS memory if requested.
- Updated some third-party dependencies.

### Version 1.1.1, November 28, 2023

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

- Implement multiple database support - allow the exporter to publish metrics for multiple database instances,
- Implement vault support - allow the exporter to obtain database connection information from a secure vault,
- 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,
- Provide the option to have the Oracle client outside of the container image, e.g., on a shared volume,
- Implement the ability to update the configuration dynamically, i.e., without a restart,
Expand Down Expand Up @@ -204,6 +212,7 @@ Now, you provide the connection details using these variables:
- `DB_USERNAME` is the database username, e.g., `pdbadmin`
- `DB_PASSWORD` is the password for that user, e.g., `Welcome12345`
- `DB_CONNECT_STRING` is the connection string, e.g., `devdb_tp?TNS_ADMIN=/wallet`
- `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.

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:

Expand Down Expand Up @@ -482,6 +491,16 @@ COPY custom-metrics.toml /
ENTRYPOINT ["/oracledb_exporter", "--custom.metrics", "/custom-metrics.toml"]
```

## Controlling memory usage

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.

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:

- 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.
- 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.
- 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.

## Grafana dashboards

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.
Expand Down
15 changes: 9 additions & 6 deletions collector/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
}(time.Now())

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

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

level.Debug(e.logger).Log("msg", "connection properties: "+fmt.Sprint(P))

db := sql.OpenDB(godror.NewConnector(P))
// if err != nil {
// level.Error(e.logger).Log("Error while connecting to", e.dsn)
// return err
// }
level.Debug(e.logger).Log("msg", "set max idle connections to "+strconv.Itoa(e.config.MaxIdleConns))
db.SetMaxIdleConns(e.config.MaxIdleConns)
level.Debug(e.logger).Log("msg", "set max open connections to "+strconv.Itoa(e.config.MaxOpenConns))
db.SetMaxOpenConns(e.config.MaxOpenConns)
level.Debug(e.logger).Log("msg", "Successfully connected to "+maskDsn(e.connectString))
level.Debug(e.logger).Log("msg", "disable go connection pooling, to allow use of oracle's instead")
db.SetMaxIdleConns(0)
db.SetMaxOpenConns(0)
db.SetConnMaxLifetime(0)
level.Debug(e.logger).Log("msg", "Successfully configured connection to "+maskDsn(e.connectString))
e.db = db
return nil
}
Expand Down
23 changes: 12 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
module github.com/oracle/oracle-db-appdev-monitoring

go 1.20
go 1.21

toolchain go1.21.4

require (
github.com/BurntSushi/toml v1.3.2
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/go-kit/log v0.2.1
github.com/godror/godror v0.39.3
github.com/godror/godror v0.41.0
github.com/oracle/oci-go-sdk/v65 v65.53.0
github.com/prometheus/client_golang v1.17.0
github.com/prometheus/client_golang v1.18.0
github.com/prometheus/common v0.45.0
github.com/prometheus/exporter-toolkit v0.10.0
github.com/prometheus/exporter-toolkit v0.11.0
)

require (
Expand All @@ -23,20 +25,19 @@ require (
github.com/gofrs/flock v0.8.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/sony/gobreaker v0.5.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
Loading