Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
app
config Prefer IfUnlessModifier to if block Sep 23, 2018
db
public Add ruby-gatekeeper project Jul 9, 2018
.rubocop.yml
.rubocop_todo.yml
Gemfile
Gemfile.lock
LICENSE Add ruby-gatekeeper project Jul 9, 2018
README.md
Rakefile
config.ru Rubocop all of the things in Gatekeeper Sep 23, 2018
server.rb Remove unneeded ()s Sep 23, 2018

README.md

ruby-gatekeeper

Overview

This is an example application modeled after Honeycomb's API server (codenamed Gatekeeper). To see real data output by an app like this, and to learn about a real issue surfaced by exploring production data with Honeycomb, check out our Gatekeeper Tour Guide.

This app implements the /1/events/ endpoint of our public API This app was written in order to show how instrumentation moves through a more mature application - specifically addressing concepts like:

  • Context propagation
  • Adding complex objects to instrumentation
  • How timers fit in larger blocks of logic

Download or Build

First, create and activate a virtual environment by downloading the code or cloning the repository.

To install the requirements, run:

bundle install

Start the application:

ruby server.rb

The server will start listening on port 4567.

Run the server

Before you launch the server, set the following environment variables:

  • HONEYCOMB_WRITEKEY - specifies the API key (aka "write key") available from your account page
  • HONEYCOMB_DATASET - specify the dataset to where instrumentation events will be sent
  • HONEYCOMB_SERVICE - specify the name of your app (defaults to the dataset name)

Running the apiary server will start it listening on port 4567. Send HTTP POSTs to the /1/events/<dataset-name> endpoint with an X-HONEYCOMB-TEAM header containing one of the hardcoded api keys and with a body containing a JSON object. The server will process the POST and if everything looks good, eventually write it to /tmp/api#.log, where # is a partition number (between 1-5).

example of sending an event to the apiary server:

➜  curl -v localhost:8080/1/events/wade \
    -H "X-Honeycomb-Team: abcd123EFGH" \
    -H "X-Honeycomb-Event-Time: 2018-07-03T20:59:08.832016791Z" \
    -d '{"foo":3}'

If you want to just see the instrumentation events on the command line instead of sending them to Honeycomb, add (debug: true) to the Honeycomb.init function in server.rb. By calling Honeycomb.init(debug: true)(and after restarting your server), the instrumentation events will the Beeline will not send any events to Honeycomb, but will instead print them to your app's standard error.

Hard-coded values for X-Honeycomb-Team (required header):

  • abcd123EFGH
  • ijkl456MNOP
  • qrst789UVWX

Hard-coded values for dataset names (required in the URL):

  • wade
  • james
  • helen
  • peter
  • valentine
  • andrew

Expected values for X-HONEYCOMB-SAMPLERATE (optional): positive integers. If absent, defaults to 1

Expected values for X-HONEYCOMB-EVENT-TIME (optional): RFC3339 formatted timestamps. If absent, defaults to the current time

Any values other than those listed above will cause a HTTP status 401 (for api keys) or 400 (for dataset names) to be returned by the server along with an error message. Errors can also be generated by sending malformed JSON or broken expected headers

Example output instrumentation events you'll see in Honeycomb:

{
   "meta.beeline_version":"0.4.0",
   "meta.local_hostname":"your.localhost_name",
   "service_name":"apiary",
   "meta.package":"rack",
   "meta.package_version":"1.3",
   "type":"http_server",
   "name":"POST /1/events/james",
   "request.method":"POST",
   "request.path":"/1/events/james",
   "request.protocol":"http",
   "request.http_version":"HTTP/1.1",
   "request.host":"localhost:4567",
   "request.remote_addr":"::1",
   "request.header.user_agent":"curl/7.54.0",
   "trace.trace_id":"0212228a-6bb0-41fb-bb76-4f27dd7fbc6e",
   "trace.span_id":"0212228a-6bb0-41fb-bb76-4f27dd7fbc6e",
   "app.HTTP_X_HONEYCOMB_SAMPLERATE":"2",
   "app.HTTP_X_HONEYCOMB_TEAM":"abcd123EFGH",
   "app.HTTP_X_HONEYCOMB_EVENT_TIME":"2018-07-03T20:59:08.832016791Z",
   "app.sample_rate":2,
   "app.timer.parse_json_dur_ms":0,
   "app.team":{
      "id":1,
      "name":"RPO",
      "write_key":"abcd123EFGH"
   },
   "app.timer.validated_writekey_dur_ms":0,
   "app.dataset":{
      "id":2,
      "name":"james",
      "partition_list":[
         1,
         2,
         4
      ]
   },
   "app.timer.resolve_dataset_timer_dur_ms":0,
   "app.chosen_partition":1,
   "app.timer.grab_partition_dur_ms":0,
   "app.event_time":"2018-07-03T20:59:08.832016791Z",
   "app.timer.event_time_delta_sec":1530922191,
   "app.hit_schema_cache":true,
   "app.timer.get_schema":0,
   "response.status_code":200,
   "duration_ms":2.296
}