Skip to content

Commit

Permalink
Update README, add flags
Browse files Browse the repository at this point in the history
  • Loading branch information
RubenHoms committed Apr 20, 2018
1 parent fc4a561 commit cbe3e7c
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 12 deletions.
97 changes: 95 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,97 @@
# opensips_exporter

Work In Progress
This exporter exposes OpenSIPS metrics for consumption by Prometheus using the Unix socket
provided by OpenSIPS. It uses the
OpenSIPS [Management Interface](http://www.opensips.org/Documentation/Interface-MI-1-11) to gather
these statistics.

Currently, this opensips_exporter doesn't work. More documentation to come.
Tested and developed for OpenSIPS 1.11. Though the Management Interface to gather metrics is available
in other OpenSIPS versions.

## Usage
Make sure `$GOPATH/bin` is in your `$PATH`.
```
Usage of opensips_exporter:
-path string
The path where metrics will be served (default "/metrics")
-port string
Port on which the OpenSIPS exporter listens. (default "9737")
-socket string
Path to the socket file for OpenSIPS. (default "/var/run/ser-fg/ser.sock")
```

## Exported Metrics

| Metric | Meaning | Labels |
| ------ | ------- | ------ |
| opensips_core_bad_URIs_rcvd | Number of URIs that OpenSIPS failed to parse. | |
| opensips_core_bad_msg_hdr | Number of SIP headers that OpenSIPS failed to parse. | |
| opensips_core_replies | Number of received replies by OpenSIPS. | kind|
| opensips_core_replies_total | Total number of received replies by OpenSIPS. | |
| opensips_core_request | Number of requests by OpenSIPS. | kind |
| opensips_core_requests_total | Total number of received requests by OpenSIPS. | |
| opensips_core_unsupported_methods | Number of non-standard methods encountered by OpenSIPS while parsing SIP methods. | |
| opensips_core_uptime_seconds | Number of seconds elapsed from OpenSIPS starting. | |
| opensips_dialog_dialogs | Number of dialogs. | status |
| opensips_dialog_received | The number of dialog events received from other OpenSIPS instances. | event |
| opensips_dialog_sent | Number of replicated dialog requests send to other OpenSIPS instances. | event |
| opensips_load_load | Percentage of UDP children that are awake and processing SIP messages on the specific UDP interface. |ip, port, protocol|
| opensips_load_tcp_load | Percentage of TCP children that are awake and processing SIP messages. | |
| opensips_net_waiting | Number of bytes waiting to be consumed on an interface that OpenSIPS is listening on. | protocol |
| opensips_pkmem_fragments | Currently available number of free fragments in the private memory for OpenSIPS process. | pid |
| opensips_pkmem_free_size | Free private memory available for the OpenSIPS process. Computed as total_size - real_used_size. | pid |
| opensips_pkmem_max_used_size | The maximum amount of private memory ever used by the OpenSIPS process. | pid |
| opensips_pkmem_real_used_size | Amount of private memory requested by the OpenSIPS process, including allocator-specific metadata. | pid |
| opensips_pkmem_total_size | Total size of private memory available to the OpenSIPS process. | pid |
| opensips_pkmem_used_size | Amount of private memory requested and used by the OpenSIPS process. | pid |
| opensips_registrar_default_expire | Value of default_expire parameter. | |
| opensips_registrar_max_contacts | Value of max_contacts parameter. | |
| opensips_registrar_max_expires | Value of max_expires parameter. | |
| opensips_registrar_registrations | Number of registrations. | type |
| opensips_shmem_fragments | Total number of fragments in the shared memory. | |
| opensips_shmem_free_size | Free memory available. Computed as total_size - real_used_size | |
| opensips_shmem_max_used_size | Maximum amount of shared memory ever used by OpenSIPS processes. | |
| opensips_shmem_real_used_size | Amount of shared memory requested by OpenSIPS processes + malloc overhead | |
| opensips_shmem_total_size | Total size of shared memory available to OpenSIPS processes. | |
| opensips_shmem_used_size | Amount of shared memory requested and used by OpenSIPS processes. | |
| opensips_sl_received_ACKs | The number of received_ACKs. | |
| opensips_sl_replies | The number of replies. | type |
| opensips_sl_sent_err_replies_total | The total number of sent_err_replies. | |
| opensips_sl_sent_replies_total | The total number of sent_replies. | |
| opensips_tm_inuse_transactions | Number of transactions existing in memory at current time. | |
| opensips_tm_local_replies_total | Total number of replies local generated by TM module. | |
| opensips_tm_received_replies_total | Total number of total replies received by TM module. | |
| opensips_tm_relayed_replies_total | Total number of replies received and relayed by TM module. | |
| opensips_tm_transactions_total | Total number of transactions. | type |
| opensips_uri_negative_checks | Amount of negative URI checks. | |
| opensips_uri_positive_checks | Amount of positive URI checks. | |
| opensips_userloc_registered_users_total | Total number of AOR existing in the USRLOC memory cache for all domains. | |
| opensips_usrloc_contacts | Number of contacts existing in the USRLOC memory cache for that domain. | domain |
| opensips_usrloc_expires | Total number of expired contacts for that domain. | domain |
| opensips_usrloc_users | Number of AOR existing in the USRLOC memory cache for that domain. | domain |

## Processors

There are processors available per 'module' of OpenSIPS. The processors take the
statistics from the OpenSIPS socket and turn it into a Prometheus metric. You can
recognise a processor by the naming convention of the metrics.
For example the`opensips_core_replies` metric comes from the core module and its
processor can be found in `./processors/core_processor`.

You can find out more about the available modules in the OpenSIPS documentation.
At this time not all modules have a processor written for them. (help wanted!)

### Filtering enabled processors
It is possible to select what processors you want metrics from. You can do this by
appending `collect[]` parameters to your request. If for example you only want to
get metrics about the [core](http://www.opensips.org/Documentation/Interface-CoreStatistics-1-11)
and [usrloc](http://www.opensips.org/html/docs/modules/1.11.x/usrloc.html#idp5699792)
module you can do this as follows:
```
curl localhost:9737/metrics?collect[]=core:&collect[]=usrloc:
```

**_Note: You have to append `:` to the module name for this to work._**
## Development

To work on opensips_exporter, get a recent [Go], get a recent [dep], and
Expand All @@ -19,5 +107,10 @@ implementation of the interactions with OpenSIPS needed to get statistics from
the mi_datagram Unix socket of a running OpenSIPS. For tests, there is a mock
in the `./internal/mock` package.

Metrics from different OpenSIPS modules are extracted by processors defined in
the `./processors` package. To extend this exporter with metrics from other modules
create your own processor and implement the `Collector` interface. See the other
processors for inspiration.

[Go]: https://golang.org/doc/install (Getting Started - The Go Programming Language)
[dep]: https://golang.github.io/dep/docs/installation.html (Installation · dep)
37 changes: 30 additions & 7 deletions opensips_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import (
"log"
"net/http"

"flag"
"os"
"strings"

"github.com/VoIPGRID/opensips_exporter/opensips"
"github.com/VoIPGRID/opensips_exporter/processors"
"github.com/prometheus/client_golang/prometheus"
Expand All @@ -14,6 +18,8 @@ import (
var o *opensips.OpenSIPS
var collectAll = []string{"core:", "shmem:", "net:", "uri:", "tm:", "sl:", "usrloc:", "dialog:", "registrar:", "pkmem:", "load:"}

const envPrefix = "OPENSIPS_EXPORTER"

func handler(w http.ResponseWriter, r *http.Request) {
collect := r.URL.Query()["collect[]"]
collectors := make(map[prometheus.Collector]bool)
Expand Down Expand Up @@ -58,28 +64,45 @@ func handler(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
}

// strflag is like flag.String, with value overridden by an environment
// variable (when present). e.g. with socket path, the env var used as default
// is OPENSIPS_EXPORTER_SOCKET_PATH, if present in env.
func strflag(name string, value string, usage string) *string {
if v, ok := os.LookupEnv(envPrefix + strings.ToUpper(name)); ok {
return flag.String(name, v, usage)
}
return flag.String(name, value, usage)
}

var (
socketPath *string
metricsPath *string
port *string
)

func main() {
listenAddress := ":9737" // TODO: make this a flag
metricsPath := "/metrics" // TODO: maybe make this a flag
socketPath := "/var/run/ser-fg/ser.sock" // TODO: make this a flag or even a mandatory argument
port = strflag("port", "9737", "Port on which the OpenSIPS exporter listens.")
metricsPath = strflag("path", "/metrics", "The path where metrics will be served")
socketPath = strflag("socket", "/var/run/ser-fg/ser.sock", "Path to the socket file for OpenSIPS.")
flag.Parse()

// This part is to mock up setting up and using the Management
// Interface. Replace/remove this eventually.
var err error
o, err = opensips.New(socketPath)
o, err = opensips.New(*socketPath)
if err != nil {
log.Fatalf("failed to open socket: %v\n", err)
}

http.HandleFunc(metricsPath, handler)
http.HandleFunc(*metricsPath, handler)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<html>
<head><title>OpenSIPS Exporter</title></head>
<body>
<h1>OpenSIPS Exporter</h1>
<p><a href="` + metricsPath + `">Metrics</a></p>
<p><a href="` + *metricsPath + `">Metrics</a></p>
</body>
</html>`))
})
http.ListenAndServe(listenAddress, nil)
http.ListenAndServe(":"+*port, nil)
}
6 changes: 3 additions & 3 deletions processors/registrar_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ type RegistrarProcessor struct {

var registrarLabelNames = []string{}
var registrarMetrics = map[string]metric{
"max_expires": newMetric("registrar", "max_expires", " Value of max_expires parameter.", registrarLabelNames, prometheus.GaugeValue),
"max_contacts": newMetric("registrar", "max_contacts", " Value of max_contacts parameter.", registrarLabelNames, prometheus.GaugeValue),
"default_expire": newMetric("registrar", "default_expire", " Value of default_expire parameter.", registrarLabelNames, prometheus.GaugeValue),
"max_expires": newMetric("registrar", "max_expires", "Value of max_expires parameter.", registrarLabelNames, prometheus.GaugeValue),
"max_contacts": newMetric("registrar", "max_contacts", "Value of max_contacts parameter.", registrarLabelNames, prometheus.GaugeValue),
"default_expire": newMetric("registrar", "default_expire", "Value of default_expire parameter.", registrarLabelNames, prometheus.GaugeValue),
"accepted_regs": newMetric("registrar", "registrations", "Number of registrations.", []string{"type"}, prometheus.CounterValue),
"rejected_regs": newMetric("registrar", "registrations", "Number of registrations.", []string{"type"}, prometheus.CounterValue),
}
Expand Down

0 comments on commit cbe3e7c

Please sign in to comment.