Skip to content

Instantly share code, notes, and snippets.

@xunker
Created August 13, 2025 18:40
Show Gist options
  • Save xunker/91edd10c5e1917160fb8cebba81b39bc to your computer and use it in GitHub Desktop.
Save xunker/91edd10c5e1917160fb8cebba81b39bc to your computer and use it in GitHub Desktop.
Get a CSV of all occurences of a Rollbar error or message
#!/usr/bin/env ruby
#
# Writes a CSV of all available occurences of a Rollbar exception/error/message.
#
# Run via `ruby rollbar_occurences.rb`, or `chmod +x rollbar_occurences.rb`
# (one time only) and then `./rollbar_occurences.rb`.
#
# Requires the Rollbar-api gem (https://rubygems.org/gems/rollbar-api) and
# Ruby v2.3 or greater.
#
# Also requires a project auth token from Rollbar for the project
#
# Released under terms of GPL v3 where applicable.
#
def usage(exit_status = 0)
puts <<~USAGE
usage:
rollbar_occurences.rb <counterId>
"counterId" is found in the Rollbar URL for an exception:
https://app.rollbar.com/a/{orgName}/fix/item/{projectName}/{counterId}
example:
https://app.rollbar.com/a/contoso/fix/item/project-one/458356
Required Environment Variables:
ROLLBAR_API_TOKEN The API token for the Rollbar project. A read-only
token is recommended.
ROLLBAR_API_PROJECT The name of the project("{projectName}" in URL).
These can be set either via `export ROLLBAR_API_TOKEN=xxx` or inline as
`ROLLBAR_API_TOKEN=xxx ROLLBAR_API_PROJECT=yyy rollbar_occurences.rb <id>`
USAGE
exit(exit_status)
end
def fatal_error(message, show_usage: false, exit_status: 0)
puts "Error: #{message}"
if show_usage
puts '-'*80
usage(exit_status)
else
exit(exit_status)
end
end
unless RUBY_VERSION.to_f >= 2.3
fatal_error("Ruby >= 2.3 is required, but you are using #{RUBY_VERSION}.", exit_status: 1)
end
begin
require 'rollbar_api'
rescue LoadError
message = <<~MESSAGE
The "rollbar-api" Gem (https://rubygems.org/gems/rollbar-api) is required. \
You can try to install it with "gem install rollbar-api".
MESSAGE
fatal_error(message, exit_status: 1)
end
%w[ROLLBAR_API_PROJECT ROLLBAR_API_TOKEN].each do |env_var|
next if ENV[env_var].to_s.length.positive?
fatal_error(
"#{env_var} environment variable not found or not set.",
exit_status: 1,
show_usage: true
)
end
if %w[-h --help help].include?(ARGV[0])
usage
end
counter_id = ARGV[0].to_i
unless counter_id.positive?
fatal_error(
'counterId argument missing or not a number.',
exit_status: 1,
show_usage: true
)
end
# disable the noisy logger
RollbarApi.logger = Logger.new(nil)
RollbarApi::Project.configure(
ENV['ROLLBAR_API_PROJECT'],
ENV['ROLLBAR_API_TOKEN']
)
project = RollbarApi::Project.find(ENV['ROLLBAR_API_PROJECT'])
item = project.get("/api/1/item_by_counter/#{counter_id}")
item_id = item.result['itemId']
instance_list = []
more_to_load = true
page = 1
File.open("instances_#{counter_id}.csv", 'w') do |file|
puts "Created #{file.path}"
file.puts(
%i[
id
when
class
message
uri
url
requested_filename
file_extention
ip
user_id
user_agent
body
].join(',')
)
while more_to_load
puts "loading page #{page}"
instances = project.get(
"api/1/item/#{item_id}/instances",
page: page,
limit: 100
)
instances.result.instances.each do |inst|
user_agent = if !(headers = inst.data.request&.headers).nil?
headers['User-Agent']
end
request_url = inst.data.request&.url.to_s
requested_filename = if (m = request_url.match(/\/([^\/]+)\z/))
m[1]
end
file_extention = if (requested_filename && (m = requested_filename.match(/\.(.{1,8})\z/)))
m[1]
end
# `.gsub(',', '%2C')` serves to replace a comma with the URL-Encoding
# equivalent "%2C" because there is no standard way to escape a comma in
# a CSV file.
# .gsub("\n", '\n') is the same, but for newline characters where they
# are turned in to the literal '\n' string.
file.puts [
inst.id,
Time.at(inst.timestamp),
inst.data.body&.trace&.exception&.class,
inst.data.body&.trace&.exception&.message.to_s.gsub("\n", '\n'),
inst.data.body&.trace&.extra&.uri.to_s.gsub(',', '%2C'),
request_url.gsub(',', '%2C'),
requested_filename.gsub(',', '%2C'),
file_extention,
inst.data.request&.user_ip,
inst.data.body&.trace&.extra&.custom_params&.user_id,
user_agent,
inst.data.request&.body
].join(',')
end
page += 1
more_to_load = instances.result.instances.length.positive?
end
puts "Finished writing to #{file.path}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment