Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Bugsnag Error Widget for Dashing

#Bugsnag Error Widget for

Dashing Widget for displaying Bugsnag errors count. Supports any number of bugsnag projects and error configurations.



To use this widget you have two options:

  • Let Dashing do the hard work for you: run
dashing install f7ed811ea0fcecb5c4ace4c7e029cd9e

(this will copy all files in place). Then edit bugsnag_errors.rb to configure your Bugsnag credentials and set up the list of errors you are interested in.

  • Or do it all yourself: copy bugsnag_errors.html,, and bugsnag_errors.scss into the /widgets/bugsnag_errors directory. Put the bugsnag_errors.rb file in your /jobs folder. Then edit bugsnag_errors.rb to configure your Bugsnag credentials and set up the list of errors you are interested in.

After that, install dependencies:

  • Add gem 'json' to your Gemfile and run bundle

To include this widget in a dashboard, add the following snippet to the dashboard layout file:

<li data-row="1" data-col="2" data-sizex="1" data-sizey="1">
    <div data-id="<bugsnag_errors_job_id>" data-view="BugsnagErrors"></div>

##How to configure bugsnag_errors.rb

  • Modify CREDENTIALS object username and password.
  • Inside job_mapping, add one entry per error configuration you want to fetch (i.e production errors, production warnings, dev errors, open errors...) following the structure of the sample jobs you can find in bugsnag_errors.rb.
  • Use the key of the job entry you just configured as yor data-id in your dashboard html.
  • You can add any number of jobs and therefore you can have any number of html BugsnagErrors tags.

##Widget background color The widget is colored depending on the error severity:

  • red for error
  • orange for warning
  • green for info

##Where is my project id?

##Based on bugsnag API All configurable job properties inside bugsnag_errors.rb are documented in

class Dashing.BugsnagErrors extends Dashing.Widget
@accessor 'current', Dashing.AnimatedValue
@accessor 'bgColor', ->
if @get('type') == "info"
else if @get('type') == "error"
else if @get('type') == "warning"
onData: (data) ->
$(@node).css('background-color', @get('bgColor'))
<h1 class="title" data-bind="title"></h1>
<h2 class="value" data-bind="current | shortenedNumber | prepend prefix | append suffix"></h2>
<p class="more-info" data-bind="moreinfo"></p>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require 'net/http'
require 'json'
require 'time'
# Change credentials to your own
'auth_name' => 'your_bugsnag_username',
'auth_password' => 'your_bugsnag_password'
# The keys of this mapping must be unique identifiers. You will use them as the data-id of the HTML tags.
# To get your account id, open your browser, log into, and load
# Then, to get your project's id, load this url:<your_account_id>/projects
# For further info about the different properties, have a look at
# All properties (except project_id and auth) can have one or more values (comma separated), or could be left empty ('').
job_mapping = {
'first_error_job_config' => {
:project_id => 'your_bugsnag_project_id', #i.e. 54ed754b7765626703005b80.
:severity => 'error', # error/warning/info
:stages => 'pro', # your defined stages
:versions => 'gte1.0.1', # i.e. eq1.0.0 (errors affecting 1.0.0), gte1.0.1 (errors affecting >= 1.0.1)
:status => 'open', # new/open/fixed/snoozed/ignored/in progress
'second_error_job_config' => {
:project_id => 'your_bugsnag_project_id',
:severity => 'info,warning',
:stages => 'dev,pro',
:versions => 'eq1.0.0',
:status => 'open,fixed',
def get_errors_count(config)
http =, BUGSNAG_API_URL.port)
http.use_ssl = BUGSNAG_API_URL.scheme == 'https'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request ="/projects/#{config[:project_id]}/errors?severity=#{config[:severity]}&status=#{config[:status]}&release_stages=#{config[:stages]}&app_versions=#{config[:versions]}")
request.basic_auth(config[:auth]['auth_name'], config[:auth]['auth_password'])
response = http.request(request)
count = JSON.parse(response.body.force_encoding("UTF-8")).count
# Resolve pagination if needed
if (response['Link'])
until (response['Link'].index('next') == nil)
# Read next page URL and obtain data
request =['Link'], '<', '>'))
request.basic_auth(config[:auth]['auth_name'], config[:auth]['auth_password'])
response = http.request(request)
count = count + JSON.parse(response.body.force_encoding("UTF-8")).count
return count
def string_between_markers(string, marker1, marker2)
string[/#{Regexp.escape(marker1)}(.*?)#{Regexp.escape(marker2)}/m, 1]
job_mapping.each do |title, config|
SCHEDULER.every '60s', :first_in => 0 do |job|
errors_count = get_errors_count(config)
send_event(title, {
current: errors_count,
type: config[:severity]
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #47bbb3;
$value-color: #fff;
$title-color: rgba(255, 255, 255, 0.7);
$moreinfo-color: rgba(255, 255, 255, 0.7);
// ----------------------------------------------------------------------------
// Widget-bugsnag-errors styles
// ----------------------------------------------------------------------------
.widget-bugsnag-errors {
background-color: $background-color;
.title {
color: $title-color;
.value {
color: $value-color;
font-size: 130px;
.more-info {
color: $moreinfo-color;
.updated-at {
color: rgba(0, 0, 0, 0.3);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.