dogstatsd
1 Introduction
2 Setup a socket
sock-create
sock-send
sock-close
3 Metrics
counter
gauge
histogram
set
4 Timers
timer
with-timer
5 Buffers
make-buffered
6 Events
event
7 Service Checks
OK
WARNING
CRITICAL
UNKNOWN
service-check
7.1

dogstatsd

Darren Newton <[email protected]>

 (require dogstatsd) package: racket-dogstatsd

1 Introduction

Provides a Racket DogStatsD client for sending metrics to Datadog. DogStatsD is an extension of the StatsD protocol developed by Etsy for metrics aggregation. DogStatsD requires that you have the Datadog Agent running on the host, or another service listening for udp traffic on port 8125.

Example:

(require racket/list
         dogstatsd)
 
(module+ main
  ; Create a socket on 127.0.0.1:8125 which the Agent listens on
  (sock-create)
 
  (define (send-times)
    ; Wrap some code with a timer metric - the elapsed time (ms) for the execution
    ; of the body will be sent to the agent
    (with-timer "rkt.timer" #:tags '("proc:send-times" "proc:with-timer")
      (let ([xs (range 10)])
        (for ([i xs])
          ; Send a counter metric
          (counter "rkt.counter" i #:tags '("proc:send-times"
                                            "aeon:12")
                     #:sample-rate 0.25))))
    (println (current-seconds))
    (sleep 2)
    (send-times))
  (send-times))

2 Setup a socket

procedure

(sock-create [#:host-name? host-name    
  #:host-port? host-port])  udp?
  host-name : string? = "127.0.0.1"
  host-port : number? = 8125
Create and open a udp? socket for host-name on host-port. You should only do this once in your program.

procedure

(sock-send metric)  boolean?

  metric : string?
Manually send a metric string on the socket created with sock-create. This is a low-level building block used by the metric procedures.

procedure

(sock-close)  void?

Close the currently open socket.

3 Metrics

procedure

(counter name    
  value    
  [#:sample-rate sample-rate    
  #:tags tags])  void?
  name : string?
  value : number?
  sample-rate : number? = #f
  tags : (listof string?) = #f
Send a DogStatsD Counter metric. Counters track how many times something happens per second, like page views or downloads.

Examples:

; Simple counter
(counter "dogeapp.downloads" 5)
 
; Counter with tags
(counter "dogeapp.dowloads" 5 #:tags '("size:small" "type:shibainu"))
 
; Counter with sample-rate
(counter "dogeapp.dowloads" 5 #:sample-rate 0.25)

procedure

(gauge name    
  value    
  [#:sample-rate sample-rate    
  #:tags tags])  void?
  name : string?
  value : number?
  sample-rate : number? = #f
  tags : (listof string?) = #f
Send a DogStatsD Gauge metric. Gauges track the ebb and flow of a particular metric value over time, like the number of active users on a website.

Examples:

; Simple gauge
(gauge "dogeapp.users.active" (get-active-users))
 
; Gauge with tags
(gauge "dogeapp.users.active" (get-active-users) #:tags '("type:shibainu"))
 
; Gauge with sample-rate
(gauge "dogeapp.users.active" (get-active-users) #:sample-rate 0.25)

procedure

(histogram name    
  value    
  [#:sample-rate sample-rate    
  #:tags tags])  void?
  name : string?
  value : number?
  sample-rate : number? = #f
  tags : (listof string?) = #f
Send a DogStatsD Histogram metric. Histograms calculate the statistical distribution of any kind of value. For instance you can track distributions for anything, like the size of files users upload to your site.

Examples:

; Simple histogram
(histogram "dogeapp.uploads.filesize" file-size)
 
; Histogram with tags
(histogram "dogeapp.uploads.filesize" file-size #:tags '("type:shibainu"))
 
; Histogram with sample-rate
(histogram "dogeapp.uploads.filesize" file-size #:sample-rate 0.45)

procedure

(set name    
  value    
  [#:sample-rate sample-rate    
  #:tags tags])  void?
  name : string?
  value : (or/c string? number?)
  sample-rate : number? = #f
  tags : (listof string?) = #f
Send a DogStatsD Set metric. Sets count the number of unique elements in a group. To track the number of unique visitors to your site, use a set.

Examples:

; Simple set
(set "dogeapp.users.uniques" (current-user-id))
 
; Set with tags
(set "dogeapp.users.uniques" (current-user-id) #:tags '("type:shibainu"))
 
; Set with sample-rate
(set "dogeapp.users.uniques" (current-user-id) #:sample-rate 0.75)

4 Timers

Timers measure the amount of time a section of code takes to execute, like the time it takes to render a web page. This module provides a manual timer procedure and a with-timer macro you can wrap code with.

procedure

(timer name    
  value    
  [#:sample-rate sample-rate    
  #:tags tags])  void?
  name : string?
  value : number?
  sample-rate : number? = #f
  tags : (listof string?) = #f
Manually send a DogStatsD timing metrics. The value should be the milliseconds you wish to record. Read the documentation on Timers, as they create Histogram metrics automatically.

Examples:

(define timed (... some procedure that returns milliseconds you wish to record ...))
 
; Simple timer
(timer "dogeapp.page.render" timed)
 
; Timer with tags
(timer "dogeapp.page.render" timed #:tags '("type:shibainu"))
 
; Timer with sample-rate
(timer "dogeapp.page.render" timed #:sample-rate 0.45)

syntax

(with-timer name tags-clause sample-clause
            body ...)
 
name = metric-name
  | ...
     
tags-clause = 
  | #:tags (tags-id:id)
  | #:tags (tags-id:id) ...
     
sample-clause = 
  | #:sample-rate sample-id:id
  | #:sample-rate sample-id:id ...
 
  name : string?
  tags-clause : (listof string?)
  sample-clause : number?
with-timer provides an easy to use macro for timing chunks of code. Wrapping your function or let-body will automatically time its execution and send the metric. It also returns the value of the executed body clause, so you can use it in a define or let if you like.

Example:

; Time the execution of code in milliseconds and send metric to Agent
(with-timer "dogeapp.page.render" #:tags '("type:threaded")
  ; code you want to instrument here
  (...))
 
; Used in a define, will set timed-value to the result of (call-databass)
; and send the timing metric to the Agent
(define timed-value (with-timer "dogeapp.databass.call" (call-databass ...)))

5 Buffers

For performance sensitive code you may want to batch up metrics before sending to the Agent. In this case you can create buffered versions of a metric, which only dispatch to the Agent when their limit has been reached.

procedure

(make-buffered base-proc [limit])  procedure?

  base-proc : procedure?
  limit : number? = 25
Wraps a metric procedure such as counter with a buffer, which will store metrics until limit is reached. The default is a buffer of size 25.

Examples:

; Will buffer 15 metrics before sending to the Agent
(define buffered-counter (make-buffered counter 15))
 
; Only the first 15 metrics will be sent
(for ([x (range 17)])
     (buffered-counter "dogeapp.items" x #:tags '("type:buffered")))

6 Events

procedure

(event title    
  text    
  [#:timestamp timestamp    
  #:hostname hostname    
  #:aggregation-ket aggregation-key    
  #:priority priority    
  #:source-type-name source-type-name    
  #:alert-type alert-type    
  #:tags tags])  void?
  title : string?
  text : string?
  timestamp : number? = #f
  hostname : string? = #f
  aggregation-key : string? = #f
  priority : (one-of/c "normal" "low") = "normal"
  source-type-name : string? = #f
  alert-type : (one-of/c "info" "error" "warning" "success")
   = "info"
  tags : (listof string?) = #f
Send a DogStatsD Event. DogStatsD can emit events to your Datadog event stream. For example, you may want to see errors and exceptions in Datadog.

Example:

(define (render-page page)
  (with-handlers ([exn:fail?
                   (λ (e) (event "Page render error" (exn:fail-message e)
                           #:alert-type "error"))])
    ... render page ...))

7 Service Checks

DogStatsD can send Service checks to track the status of services your application depends on.

Status constants

value

OK : number? = 0

value

WARNING : number? = 1

value

CRITICAL : number? = 2

value

UNKNOWN : number? = 3

Convenient constants to use for status in service-check.

procedure

(service-check name    
  status    
  [#:timestamp timestamp    
  #:hostname hostname    
  #:message message    
  #:tags tags])  void?
  name : string?
  status : (one-of/c OK WARNING CRITICAL UNKNOWN)
  timestamp : number? = #f
  hostname : string? = #f
  message : string? = #f
  tags : (listof string?) = #f
Example:

(define (get-redis-connection)
  (with-handlers ([exn:fail?
                   (λ (e) (service-check "dogeapp.redis.connection" CRITICAL
                           #:message (exn:fail-message e)))])
    (define conn ...)
    (serivce-check "dogeapp.redis.connection" OK)
    conn))