Get up to 50% off! Limited time only: Learn More.

Customizing Your Incident Management Workflow With the VictorOps API

Scott Fitzpatrick May 20, 2019

DevOps Monitoring & Alerting API
Customizing Your Incident Management Workflow With the VictorOps API Blog Banner Image

One critical aspect of application support is an on-call strategy allowing the management of application issues outside of typical business hours. The effectiveness of a DevOps or IT on-call strategy is defined by its ability to resolve high-priority incidents in a timely manner. VictorOps provides a solution for the challenges associated with incident management through the use of collaborative incident management software.

Having an on-call strategy is critical for incident management. But, the tricky thing about planning an on-call strategy is that everyone’s needs are different. The scheduling, types of notifications, escalation paths, and so on that work for one business may not meet the needs of another. There is no one-size-fits-all approach to on-call incident management.

That’s why VictorOps provides an API allowing organizations to customize their incident management workflow and tailor it to their needs. In this article, I provide an introduction to the VictorOps API by explaining how it works. I also walk through a code implementation that uses multiple API methods to provide an example of how the VictorOps API can be leveraged to increase incident visibility and improve the efficiency of an organization’s incident management workflow.

Introducing the VictorOps API

APIs exist to give developers access to the features and data of a particular application or service. Many of the features and data associated with an organization’s use of the VictorOps platform are accessible through the use of their API. With methods ranging from pulling on-call schedule data to creating/updating user accounts and managing incident information, the VictorOps API provides functionality that any organization with a VictorOps subscription can leverage to improve incident management processes.

All of the VictorOps packages offer unlimited API calls per month. The unlimited use of the VictorOps API permits a DevOps organization to customize the incident management pipeline as they see fit; without the associated fear of using up a finite number of requests prior to the end of a given month.

So let’s take a look at a sample application that utilizes the VictorOps API.

Improving your incident management workflow with the VictorOps API

What are we building?

In this particular example, we’ll be building a single-page web application containing a form that we can use to report software issues to the development team. The form will contain fields for the following data to be submitted with the request:

  • Reporter username - This is the VictorOps username for the person reporting the bug.
  • Issue summary - A short description of the bug being reported. This will essentially serve as a title for the incident being recorded in the VictorOps portal.
  • Issue details - A long description of the issue. This is where the reporter can provide the development team with all the necessary information they need to resolve the incident.
  • Escalation - The escalation field will be represented by a group of checkboxes. The selection will represent the escalation policy (or policies) that will be executed as part of incident creation. Essentially, this will determine who is notified of the issue being reported. Escalation policies can be configured to notify the on-duty user(s) for a particular team, or even to notify a specific user, whether they are on-call or not. Each incident can be associated with one or more escalation policies — thus involving every necessary asset to get the issue resolved as quickly as possible.

In order for this application to be functional, we’ll have to utilize two of the API methods provided by VictorOps — the first of which is a call to pull the escalation policies configured for the development team as the data that will back the escalation field described above. The development team as well as the escalation policies we’ll be pulling have been configured by myself in the VictorOps portal (see Figure 1). The second API call we’ll need to make will be on submission of the form. This call will create the incident within the VictorOps portal for the reporting account.

Figure 1 VictorOps Escalation Policies for Development Teams

Fig. 1: Development team with two Escalation Policies (UI/UX and Database) configured in the VictorOps portal.

DevOps in Incident Management

Building the application

I have chosen to utilize the Vaadin Flow web framework for my implementation. Vaadin Flow is a Java web framework that allows me to quickly spin up a web page containing an incident reporting form. There are two classes in my example that are key to understanding the implementation:

  • MainView.java - sets the layout for the page and holds a label component detailing to the user that this tool is for reporting incidents to the development team, plus the Incident Form itself. (See Figure 2)
  • IncidentForm.java - a component representing the form itself; also where we’ll make two calls to the VictorOps API. (See Figure 3)
  @Route("report-to-development")
  public class MainView extends VerticalLayout {
      private static final long serialVersionUID = 1L;
    
      public MainView() {
        add(new Label("Report Development Bug:"));
        add(new IncidentForm());
    }
  }

Fig. 2: MainView.java

{ public IncidentForm() {
    ...
    escPolCBGroup.setItems(getEscalationPolicies());
    ...
    submit.addClickListener(event -> createIncidentInVO());
}

Fig. 3: A snippet showing a portion of IncidentForm.java

Making our API calls

The code snippet in Figure 3:

scPolCBGroup.setItems(getEscalationPolicies());

sets the items associated with the escalation policy checkbox group. This will be represented in the UI as a group of checkboxes listing the available escalation policies for the development team. The list of items passed to the setItems(List) method is retrieved using the getEscalationPolicies() method. This is where we’ll make our first API call, with the intent to pull all escalation policies associated with the development team. From the API documentation for this particular call, we know the following:

  • This will be an HTTP GET request
  • The URL will be: https://api.victorops.com/api-public/v1/team/{team_slug_value_for_development_team}/policies
  • The following request headers will be required to complete the call successfully:
    • Content-Type with a value of application/json
    • X-VO-Api-Id representing the VictorOps API ID value for the subscribing organization
    • X-VO-Api-Key representing the API Key provided by VictorOps to allow the organization access to retrieve the data.

As a result of the request, an array of escalation policies is returned in the following format:

{
"policies": [
 {
    "name": "string",
    "slug": "string"
    }
  ]
}

In Figure 4, you can see the Java implementation of the getEscalationPolicies() method where the request for the escalation policy data is made and the response JSON array is parsed successfully to create EscalationPolicy objects for the Escalation checkbox group.

public List<EscalationPolicy> getEscalationPolicies() {
	try {
    	CloseableHttpClient client = HttpClientBuilder.create().build();
	    HttpGet request = new HttpGet(url + "/api-public/v1/team/“ + teamSlug + “/policies");
	    request.setHeader("Content-Type", "application/json");
	    request.setHeader("X-VO-Api-Id", apiId);
	    request.setHeader("X-VO-Api-Key", apiKey);

	    CloseableHttpResponse response = client.execute(request);
	    BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
	    StringBuilder sb = new StringBuilder();
	    String line = null;
	    while ((line = reader.readLine()) != null) {
		    sb.append(line + "\n");
	    }

    	JSONObject policies = new JSONObject(sb.toString());
	    JSONArray policyArray = policies.getJSONArray("policies");
	    List<EscalationPolicy> escalationPolicies = new ArrayList<EscalationPolicy>();
	    for (int i = 0; i < policyArray.length(); i++) {
		    JSONObject policy = policyArray.getJSONObject(i);
	    	EscalationPolicy escPol = new EscalationPolicy(policy.getString("name"), policy.getString("slug"));
		    escalationPolicies.add(escPol);
	    }

    	response.close();
    	client.close();

    	return escalationPolicies;
    } catch (IOException e) {
    	return new ArrayList<EscalationPolicy>();
    }
}

Fig. 4: API request to retrieve escalation policies for the development team

Next, we have our createIncidentInVO() method. This method takes the values from each of the form fields and uses them to produce the request to create an incident in the VictorOps portal. From the documentation, we know the following about the create incident API method:

  • This will be an HTTP POST request
  • The URL will be: https://api.victorops.com/api-public/v1/incidents
  • The following request headers will be required to complete the call successfully:
    • Content-Type with a value of application/json
    • X-VO-Api-Id representing the VictorOps API ID value for the subscribing organization
    • X-VO-Api-Key representing the API Key provided by VictorOps to allow the organization access to retrieve the data.
  • In addition, the request body should be JSON in the following format:

    {
      "summary": "string",
      "details": "string"
      "userName": "string"
      "targets": [
          {
          "type": "string"
          "slug": "string"
          }
      ]
    }
    

The request will result in the following JSON response:

{
 "incidentNumber": "string",
 "error": "string"
}

Please see Figure 5 for the Java implementation of createIncidentInVO().

private void createIncidentInVO() {
	try {
    	CloseableHttpClient client = HttpClientBuilder.create().build();
    	HttpPost request = new HttpPost(url + "/api-public/v1/incidents");
    	request.setHeader("Content-Type", "application/json");
    	request.setHeader("X-VO-Api-Id", apiId);
    	request.setHeader("X-VO-Api-Key", apiKey);

    	ArrayList<Target> targets = new ArrayList<Target>();

    	for (EscalationPolicy escPolicy : escPolCBGroup.getSelectedItems()) {
	    	Target target = new Target("EscalationPolicy", escPolicy.getSlug());
		    targets.add(target);
    	}

    	Incident incident = new Incident(summary.getValue(), details.getValue(), reporter.getValue(),targets);
	    String formattedRequest = new Gson().newBuilder().create().toJson(incident);

    	request.setEntity(new StringEntity(formattedRequest));
    	client.execute(request);

    	client.close();
	} catch (IOException e) {
	    throw new RuntimeException("", e);
	}
}

Fig. 5: createIncidentInVO() method representing the creation and execution of the create incident API method provided by VictorOps

Within the createIncidentInVO() method, you can see that we create an HTTP POST request with the appropriate headers. We build a list of Target objects by looping over the selected checkboxes representing the escalation policies to trigger with our incident. Then, we retrieve all text field values (username, summary, details) and pass them along with our list of targets to the incident constructor to produce our incident object. Next, the Gson plugin from Google is leveraged to take this incident object and format it appropriately for the request. The body of the request is then set and the call to VictorOps is executed in an effort to create the incident.

Let’s give it a shot

Upon page load, our form is displayed. Notice that the escalation policies are displayed as a group of checkboxes. Again, the values are the result of the API call made earlier to retrieve all escalation policies associated with the development team.

After entering test values into our form, it appears as follows:

Figure 6 Test Incident Form

Fig. 6: Filled-out form for creating a test incident

Next, we click Submit and visit our VictorOps portal. In Figure 7, you can see that the request was processed and the incident was created successfully — demonstrating that we now have a working web application for creating incidents within the VictorOps portal.

Figure 7 Successful Incident Creation in VictorOps

Fig. 7: Incident #16 was created as a result of our web application for reporting bugs to the development team

Conclusion

An incident management strategy can be a tricky process to manage. That being said, ancillary tools are often quite useful to an organization looking to provide the reporters and on-call personnel with everything they need to keep the application support pipeline functioning efficiently. When working with VictorOps’ incident management software, you are provided with access to their API. Using the VictorOps API effectively will allow you to customize your incident management workflow in a variety of ways that can help streamline many of the tedious application support processes you’re using today.

About the Author

Scott Fitzpatrick is a Fixate IO contributor and has 7 years of experience in software development. He has worked with many languages and frameworks, including Java, ColdFusion, HTML/CSS, JavaScript and SQL.

Let us help you make on-call suck less.

Get Started Now