This is the second of a two-part blog post on detecting and correcting errors with Rollbar and CircleCI, by guest contributor Jason Skowronski. Read part I here.
When you’re practicing continuous delivery, it’s essential that you monitor your application so you know that it’s performing well after deployments. You need to be notified immediately if something is wrong or if users are having a poor experience so you can resolve the issue quickly. When your monitoring solution can also tell you which code changes caused the error, you can save valuable time troubleshooting. In part one of our blog series, we showed how you can use Rollbar to track the errors occurring after each deployment in CircleCI. Rollbar shows you which new errors occurred and which ones reactivated. For any given error, it can also show you the suspected deployment after which the error first occurred.
Here in part two, we will show you how Rollbar can automatically identify the code changes that may have caused the error. This won’t help with errors caused by external factors like third party APIs or infrastructure problems, but it will help you narrow down errors due to code bugs faster. This will increase your development velocity and help you deliver a better experience to your customers.
We’ll continue our example showing how Rollbar integrates with CircleCI and GitHub to make this work.
Track deployments in CircleCI
To link the error to source code, first you need to set up CircleCI with your application. We will assume that you already have an account with CircleCI. If not, sign up and then configure the source code repository such as Git and Bitbucket. Then, follow the instructions in part one of our blog series to notify Rollbar when making a deployment.
Send your source maps to Rollbar
If you use JavaScript, Rollbar can map the error message back to your original source code using source maps. If not, you can skip this section.
Source maps are essential to debugging production code. They link the browser’s debug output back to the original source code before it was minified or transpiled. In order to display stack traces with your original code, Rollbar needs access to the source maps for your minified JavaScript.
In order to upload the source map, you need to add the Rollbar source map API call before the deployment script in the CircleCI config file.
- run:
name: Upload sourcemap to Rollbar
command: |
curl https://api.rollbar.com/api/1/sourcemap/ \
-F access_token=2a208f30fa1b4f0183adb694c4432038 \
-F version=$CIRCLE_SHA1 \
-F minified_url=https://s3.us-east-2.amazonaws.com/rollbar-example/
main.[hash].bundle.js \
-F source_map=main.[hash].bundle.js.map \
-F main.js=main.[hash].js
# Deployment script
access_token: The destination project token on Rollbar. This token is generated when a project is created on Rollbar.
environment: The deployment environment where the service is deployed. We can configure different environments such as development, staging, and production.
version: The deployed application version. This should be repository commit ID. Rollbar will create a link to the repository commit source code if the supplied version is the commit ID.
minified_url: The full URL of the minified file. Should start with http: or https:, which we’ll strip off.
source_map: The contents of the source map, as a multipart file upload.
Identify the code version
In order for Rollbar to identify the suspected deployment for an error, it has to know which version is currently deployed. One convenient way to track diversion is using the git SHA number because it uniquely identifies your code at a point in time. Since this version is set when you commit the code, it can’t be hardcoded in your application. Instead, we can insert the version at build time.
We want npm, our package builder, to insert the code version automatically, so we’ll insert a short script to do that. Let’s create a custom ts file named git.version.ts to get the latest SHA revision number of source code.
var fs = require('fs');
import { Observable } from 'rxjs';
let exec = require('child_process').exec;
const revision = new Observable<string>(s => {
exec('git rev-parse HEAD',
function (error: Error, stdout: Buffer, stderr: Buffer) {
if (error !== null) {
console.log('git error: ' + error + stderr);
}
s.next(stdout.toString().trim());
s.complete();
});
});
const branch = new Observable<string>(s => {
exec('git rev-parse --abbrev-ref HEAD',
function (error: Error, stdout: Buffer, stderr: Buffer) {
if (error !== null) {
console.log('git error: ' + error + stderr);
}
s.next(stdout.toString().trim());
s.complete();
});
});
Observable
.combineLatest(revision, branch)
.subscribe(([revision, branch]) => {
console.log(`version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'`);
const content = '// this file is automatically generated by git.version.ts script\n' +
`export const versions = {version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'};\n`;
fs.writeFileSync(
'src/environments/versions.ts',
content,
{encoding: 'utf8'}
);
});
Next, add the pre-build script in the package.json. The pre build script will automatically execute at the time of building the application, and it will create a version.ts file with git revision info such as branch, revision number, etc. You can directly access the version.ts file throughout the project.
"scripts": {
"prebuild.prod": "ts-node git.version.ts",
"build.prod": "ng build --prod --aot false --sourcemaps "
}
Tell Rollbar the code version
Now we can configure Rollbar’s code_version
variable so it can track the version number. We will read the revision number using the git.version.ts file. We’ll initizate Rollbar in our app.module.ts file as shown below.
const versions = require('../environments/versions');
const rollbarConfig = {
accessToken: 'f627d5e044a24b9987a23e54c5df352e',
captureUncaught: true,
captureUnhandledRejections: true,
enabled: true,
source_map_enabled: true,
environment: 'production',
payload: {
server: {
branch: 'master',
root: 'webpack:///./'
},
client: {
javascript: {
code_version: versions.versions.revision
}
}
}
};
export function rollbarFactory() {
return new Rollbar(rollbarConfig);
}
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [
{ provide: ErrorHandler, useClass: RollbarErrorHandler },
{ provide: Rollbar, useFactory: rollbarFactory }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Add source control integration
We would also like Rollbar to integrate with our source control repository so that when an error occurs, it can automatically link us to the proper line of code. It can also tell us when there are code changes that break the deployment.
Below, you can see that we have configured in integration with GitHub. Make sure to have the project root configured in Rollbar as shown below; it’s the source code location where the root is placed. If this is not configured properly, Rollbar will not be able link the source code to an error. In this example, the project root is /
.
Run the test cases to generate errors
Now we will test all the pieces that we just put together. We will execute our build on CircleCI, run the application, then generate a test error. This will send a test error to Rollbar so we can see how it identifies the deployment and source code next.
Find the root cause of errors
Check the Rollbar dashboard for the error logging on the Items menu tab which will show the error details along with the link to the source code file that caused the error. The error will show the suspected deployment version along with the piece of code causing the error.
Clicking on an error item in the list, we see the item detail page. Next to the trace back, we can see a link to the source code causing the error.
When you click on the link it will directly open the class in the GitHub repository and highlight the changed piece of the code, depicted in the next screenshot:
A second way to investigate the cause of errors is by using the Suspect Deploy tab. It shows the revision where the error was first observed, along with changes that were made to the code since the previous deployment. We can see the commit message indicating that an error code was introduced.
Now you can go directly from an error reported in Rollbar to the exact deployment and source code that likely caused the problem in a few clicks. No more hunting through noisy log files and searching through source code to find the responsible line. This will save you time when you’re troubleshooting issues and will help you get your production systems working faster.