{"id":18711756,"url":"https://github.com/keen/pingpong","last_synced_at":"2025-04-07T11:09:23.206Z","repository":{"id":13725903,"uuid":"16420104","full_name":"keen/pingpong","owner":"keen","description":"HTTP monitoring for developers. Richer analytics, greater flexibility.","archived":false,"fork":false,"pushed_at":"2017-04-06T23:04:31.000Z","size":2029,"stargazers_count":334,"open_issues_count":7,"forks_count":44,"subscribers_count":52,"default_branch":"master","last_synced_at":"2025-03-31T10:04:39.926Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://keen.github.io/pingpong/","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-31T20:40:32.000Z","updated_at":"2024-02-24T13:08:28.000Z","dependencies_parsed_at":"2022-09-23T14:32:00.901Z","dependency_job_id":null,"html_url":"https://github.com/keen/pingpong","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keen%2Fpingpong","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keen%2Fpingpong/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keen%2Fpingpong/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keen%2Fpingpong/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keen","download_url":"https://codeload.github.com/keen/pingpong/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247640465,"owners_count":20971557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T12:40:38.572Z","updated_at":"2025-04-07T11:09:23.183Z","avatar_url":"https://github.com/keen.png","language":"CSS","funding_links":[],"categories":["CSS"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"public/pingpong-og.png\" alt=\"Pingpong Logo\"\u003e\n\u003c/p\u003e\n\n\u003cimg src=\"https://travis-ci.org/keen/pingpong.png?branch=master\u0026foo=bar\" alt=\"Pingpong Build Status\"\u003e\n\n[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy)\n\n#### Get deeper HTTP request response analytics every second.\n\nTrack real-time performance and availability across multiple API servers to see the what, when, and how behind your system performance. So you can understand why.\n\n![Pingpong Graph](http://keen.github.io/pingpong/img/chart_02_new.png)\n\n#### How does it work?\n\n+ Pingpong sends HTTP requests to URLs you configure as frequently as once per second. It turns data about each request and response into JSON, then logs it to a custom destination.\n+ Your default data store is Keen IO’s [analytics API](https://keen.io/docs/) to capture events, run queries, and create visualizations. But it’s simple to set up another backend.\n+ Pingpong ships with [Dashboards](http://keen.github.io/dashboards/), an HTML visualization kit that lets you see and arrange your most critical response data. Built on the Keen IO analytics API, Dashboards is super-flexible and ready to be skinned, tweaked, and embedded anywhere.\n+ Pingpong captures most of the data you'd want about HTTP requests and responses. To beef up or slim down your data stream, adding custom properties specific to your infrastructure is simple.\n\n#### Choose your own install adventure.\n\n**Deploy straight to Heroku:** Pingpong is easy to install and ready for deployment to one or more Heroku regions. You can even deploy the app with a single click with this handy button:\n\n[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy)\n\n*A note on event limits:* If you're using the Keen IO backend to store events, you can send 50,000 events for free per month. As a reference, one check running every minute will create about 43,000 events in a month. Check out [more plans](https://keen.io/pricing) to get more events. We'd also love to give you a discount if you're using Pingpong, just [email us](mailto:team@keen.io?subject=Pingpong Events) your project ID and we'll get you hooked up.\n\n**Setup and deploy your own Pingpong app:** Don't run Heroku? That's cool. You can run Pingpong on any host with Ruby, even your local machine. Either way, it's up and running in less than five minutes. Just see the next section.\n\n#### Setup \u0026 Deployment\n\nPingpong is open source and easy to install. Pingpong is written in Ruby and streamlined for deployment to one or more Heroku regions. That said, you can run it on any host with Ruby, including your local machine.\n\n**Step 1:** Clone or fork this repository:\n\n```\n$ git clone git@github.com:keen/pingpong.git\n$ cd pingpong\n```\n\n**Step 2:** Install dependencies\n\n```\n$ bundle install\n```\n\nIf you don't have the `bundle` command, first `gem install bundler`.\n\n**Step 3:** Set up database tables\n\n```\n$ bundle exec rake db:create\n$ bundle exec rake db:migrate\n```\n\nThe project uses Postgres as the default database, but you can modify that in the `database.yml` file.\n\n**Step 4:** Set up the environment variables\n\n***Keen IO Setup***\n\nYou'll need to sign up for a free [Keen IO](https://keen.io?s=pingpong) account. Once your account is set up, create a new project.\n\nYou'll need to grab the `project id`, `read key`, and `write key`. Add these to a root level file called `.env`. There's a .env.sample setup with all the variables, so just run:\n\n```sh\n$ cp .env.sample .env\n```\n\nAnd edit your Keen IO variables:\n\n```\nKEEN_PROJECT_ID=xxxxxxxxxxxxxxx\nKEEN_READ_KEY=yyyyyyyyyyyyyyyyy\nKEEN_WRITE_KEY=zzzzzzzzzzzzzzzz\n```\n\n***SendGrid Setup***\n\nIf you want to send emails, you'll have to sign up for a free [SendGrid](https://sendgrid.com/user/signup) account.\n\nOnce you've done that, edit the following in your `.env` file:\n\n```\nTO_EMAIL_ADDRESS=me@test.com\nFROM_EMAIL_ADDRESS=pingpong@test.com\nSKIP_EMAIL=false\nSENDGRID_USERNAME=asdfasdfasdf\nSENDGRID_PASSWORD=12345\n```\n\n***Slack Setup***\n\nTo get notifications in Slack, you'll have to provide us with your Incoming Webhook URL. You can create an Incoming Webhook [here](https://slack.com/services/new/incoming-webhook).\n\nOnce you've got the Webhook URL, update your `.env` file:\n\n```\nSLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXXXXXXXXXXXXXX/YYYYYYYYYYY\n```\n\nThere are also some optional configurations you can edit for Slack notifications:\n\n```\nSLACK_CHANNEL='#alerts' # The channel to send notifications to\nSLACK_USERNAME='Robot' # The username the notification will come from - defaults to Pingpong\nSLACK_ICON=':rotating_light' # The icon of the user \"sending\" the notification. Can be a URL or an Emoji\nWARN_COLOR='#CCCCCC' # Hex color value used for the warning messages - defaults to #E2E541\nBAD_COLOR='#000000' # Hex color value used for the failure messages - defaults to #F25656\n```\n\n***Run the Server***\n\nNow you're ready to start the web server locally using `foreman`, which will pick up the variables in the `.env` file. [foreman](https://github.com/ddollar/foreman) comes with the [Heroku toolbelt](https://toolbelt.heroku.com/).\n\n```\n$ foreman start\n```\n\nThe Pingpong web interface should now be running on [localhost:5000](http://localhost:5000). Click on the button to create a new check, and then within a few minutes, you'll see the check data populating the charts.\n\n#### Check Properties\n\nEvery check requires the following properties:\n\n+ name: for display in charts and reports\n+ url: the fully qualified resource to check\n+ frequency: how often to sent the request, in minutes\n\nAdditionally, checks have some optional properties:\n\n+ method: GET, POST, or DELETE (defaults to GET)\n+ http_username: Username for HTTP authentication\n+ http_password: Password for HTTP authentication\n\nChecks can also have any number of custom properties, which is very useful for grouping \u0026 drill-down analysis later. Place any custom properties in the `custom` field.\n\n#### HTTP Request \u0026 Response as an Event\n\nEach time a check is run, a JSON object describing the check, request, and response is logged via a `CheckLogger` component, defaulting to `KeenCheckLogger`. Here's an example event payload:\n\n``` json\n{\n  \"check\": {\n    \"name\": \"Keen IO Web\",\n    \"url\": \"https://keen.io\",\n    \"frequency\": 5,\n    \"custom\": {\n      \"server_role\": \"https\",\n      \"is_https\": true\n    }\n  },\n  \"environment\": {\n    \"rack_env\": \"production\",\n    \"region\": \"heroku_us_east\",\n    \"location\": \"Virginia, US\"\n  },\n  \"request\": {\n    \"sent_at\": \"2013-10-12T00:00:00.000Z\",\n    \"duration\": 0.432\n  },\n  \"response\": {\n    \"successful\": true,\n    \"timed_out\": false,\n    \"status\": 200,\n    \"server\": \"TornadoServer/3.1\",\n    \"http_status\": 200,\n    \"http_reason\": \"OK\",\n    \"http_version\": \"1.1\",\n    \"content_type\": \"text/html\",\n    \"content_length\": 175,\n    \"date\": \"Wed, 16 Apr 2014 17:39:01 GMT\"\n  }\n}\n```\n\nHere's a breakdown of the major sections:\n\n+ check: properties describing the check, including any custom properties\n+ environment: properties describing where the check was made from (useful when you are running Pingpong instances across multiple datacenters)\n+ request: information about the HTTP request that was sent\n+ response: information about the HTTP response that was recorded\n\n`response.timed_out` and `response.successful` are helper properties. `response.successful` is true if the request did not timeout and the response\nstatus is between 100 and 399.\n\nIt's easy to add more fields to the `environment` section in `config.yml`, or implement a `CheckMarshaller` component that translates HTTP response fields to properties in a different way.\n\nCapturing all of these fields makes it possible to perform powerful grouping and filtering during analysis.\n\n#### Reporting and Alerting\n\nPingpong uses [Pushpop](https://github.com/pushpop/pingpong.git) to provide basic alerting and reporting functionality. This functionality can easily be extended to create your own custom alerts and reports.\n\n#### Additional Options \u0026 Recipes\n\n##### Configuration\n\nSee `config.yml` for an idea of what can be configured with settings. Examples include timeouts, pluggable components, and environment properties. \n\n##### Save a URL's JSON Response Body\n\nIf a configured check returns JSON, you can save that JSON into the request body. This allows you to monitor and analyze not only the success or failure of web calls, but also the values they can return.\n\nTo save the body, select true when creating a new check.\n\nThis example grabs the weather from the [Forecast.io API](https://developer.forecast.io/) as JSON. The weather data will be merged into the response body under the key `response.body`. Here's an example check response event (some fields omitted for clarity):\n\n``` json\n{ \n  \"response\": {\n    \"body\": {\n      \"latitude\": 37.8267,\n      \"longitude\": -122.423,\n      \"timezone\": \"America/Los_Angeles\",\n      \"currently\": {\n        \"temperature\": 56.78,\n        \"summary\": \"Overcast\",\n        \"icon\": \"cloudy\"\n      }\n    }\n  }\n}\n```\n\nNow you can visualize temperature over time by using `response.body.currently.temperature` as the target property for analysis!\n\n*Note*: The `Content-Type` header of the check's response must contain `application/json` for it to be saved. Otherwise a warning will be logged.\n\n*Note #2*: To avoid hitting Keen IO limits on the number of properties per event and per collection across all events, JSON response bodies should ideally be small and/or consistent.\n\n##### Pluggability\n\nEach major component of Pingpong is pluggable:\n\n+ Checks get run by a [pushpop](https://github.com/pushpop-project/pushpop) job in `jobs/run_checks_job.rb`\n+ `CheckMarshaller`: transforms a check and its result into the JSON payload to be logged. The efault implementation is `EnvironmentAwareCheckMarshaller`.\n+ `CheckLogger`: logs the JSON payload from the `CheckMarshaller`. The default implementation is `KeenCheckLogger`.\n\nOnce you've written an implementation for any of these components, simply replace the previous implementation's class name in `config.yml` with name of your component.\n\n##### HTTP Authentication\n\nSet the `HTTP_USERNAME` and `HTTP_PASSWORD` environment variables to enable HTTP authentication for the dashboard. Off by default.\n\n#### Custom Headers\n\nSet the `headers` property of a check to a hash of headers you'd like included with the request. For example:\n\n``` json\n{\n  \"checks\": [\n    {\n      \"name\": \"JSON API Check\",\n      \"url\": \"http://example.com/api\",\n      \"frequency\": 5,\n      \"headers\": { \"Accept\": \"application/json\" },\n      \"method\": \"GET\"\n    }\n  ]\n}\n```\n#### Inspiration\n\nPingpong was developed in-house at Keen IO to answer a few simple, but important, questions about our web and API infrastructure:\n\n+ Are any API servers or server processes slower than others?\n+ Are any web pages or API calls slow? Are any experiencing errors?\n+ Have any processes failed, or become unresponsive? Today? This month?\n+ What's the latency to each DC from a client in the US? In Europe?\n+ How much latency does using SSL add?\n\nPingpong runs all day, every day from multiple data centers around the world, helping our team understand current performance and study long-term trends. To date, Pingpong has run more than 20 million checks in production.\n\n#### Helpful Links\n\n+ [Keen IO docs](https://keen.io)\n+ [Keen IO Heroku add-on](https://addons.heroku.com/keen)\n\n#### Contributing\n\nContributions are very welcome. Here are some ideas for new features:\n\n##### Wish List\n\n+ More tabs and queries and visualizations on the dashboard\n+ More default alerts\n+ Deploy instructions for multiple platforms\n+ Ability to merge multiple data centers into one set of graphs\n+ Support for more back-ends and front-ends\n+ ~~Support for HTTP POST~~\n\nPingpong has a full set of specs. Before submitting your pull request, make sure to run them:\n\n```\n$ bundle exec rake spec\n```\n\n##### Contributors\n\n+ Josh Dzielak - [@dzello](https://github.com/dzello)\n+ Justin Johnson - [@elof](https://github.com/elof)\n+ Micah Wolfe - [@micahwolfe](https://github.com/forzalupo)\n+ Cory Watson - [@gphat](https://github.com/gphat)\n+ Loren Siebert - [@lorensiebert](https://github.com/loren)\n+ Alex Kleissner - [@hex337](https://github.com/hex337)\n+ Mariano Vallés - [@zucaritask](https://github.com/zucaritask)\n\nIf you contribute, add your name to this list!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeen%2Fpingpong","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeen%2Fpingpong","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeen%2Fpingpong/lists"}