Skip to main content

Integrate New Relic with WSO2 API Manager

In WSO2 API Manager, we have two transports. HTTP servlet transport and Passthru / NIO transport. All the web application requests are handled through HTTP servlet transport which is on 9763 port and 9443 port with ssl and here we are using tomcat inside WSO2 products. All the service requests are served via Passthru / NIO transport which is on 8082 and 8243 with ssl. When we integrate API Manager with new relic in the way discussed in blog posts [5],[6], new relic only detects the calls made to tomcat transports. So we couldn’t get the API calls related data OOTB.

But by further analyzing new relic APIs I managed to find a workaround for this problem. New relic supports publishing custom events via their insights api[1]. So what we can do is publish these data via custom API handler[2]. Following is a sample implementation of a handler that I used to test the scenario. I will attach the full project herewith[7]. I have created an osgi bundle with this implementation so after building the jar with maven you can drop into $APIM_HOME/repository/components/dropins directory. And make sure you do the necessary changes to this class to match your scenario.

 package org.wso2.carbon.custom.handler.newrelic;  
 import com.newrelic.api.agent.Agent;  
 import com.newrelic.api.agent.Trace;  
 import org.apache.commons.logging.Log;  
 import org.apache.commons.logging.LogFactory;  
 import org.apache.synapse.MessageContext;  
 import org.apache.synapse.rest.AbstractHandler;  
 import java.util.HashMap;  
 import java.util.Map;  
 import com.newrelic.api.agent.NewRelic;  
 public class NewRelicHandler extends AbstractHandler {  
   private static final Log log = LogFactory.getLog(NewRelicHandler.class);  
   @Trace  
   public boolean handleRequest(MessageContext messageContext) {  
     String endpoint = messageContext.getTo().getAddress();  
     Agent agent = NewRelic.getAgent();  
     Map<String, Object> eventAttributes = new HashMap<String, Object>();  
     eventAttributes.put("appId",32034852);  
     eventAttributes.put("appName","APIM");  
     eventAttributes.put("host","localhost");  
     eventAttributes.put("name",endpoint);  
     eventAttributes.put("transactionType","Web");  
     eventAttributes.put("type","Transaction");  
     eventAttributes.put("realAgentId",32034854);  
     eventAttributes.put("transactionSubType","API Call");  
     agent.getInsights().recordCustomEvent("API_calls", eventAttributes);  
     return true;  
   }  
   public boolean handleResponse(MessageContext messageContext) {  
     //TODO: handle response path  
     return true;  
   }  
 }  

Since you need engage this handler to all apis you need add following to velocity template as mentioned in the documentation[3]. But for existing apis you will need to add this via source view as mentioned in documentation[3]. Or you can do the same by republishing all existing apis. You will need to add this to both

 $APIM_HOME/repository/resources/api_templates/velocity_template.xml  
and
 $APIM_HOME/repository/resources/api_templates/velocity_template.xml  
files since this will be needed in default api as well.
 <handler class="org.wso2.carbon.custom.handler.newrelic.NewRelicHandler" />  

And further to execute this I added following to the newrelic.yml file.
  custom_insights_events.max_samples_stored: 5000  
  custom_insights_events.enabled: true  

Now create publish and subscribe an api (if you haven’t done already) and invoke the api several times. Then go to [4] and create a new dashboard with query

 SELECT * FROM API_calls  

You will be able to see API invocation data there. Good Luck :).


References

Comments

Popular posts from this blog

Generate JWT access tokens from WSO2 Identity Server

In Identity Server 5.2.0 we have created an interface to generate access tokens. Using that we have developed a sample to generate JWT tokens. You can find that sample under msf4j samples[1][2]. If you are build it as it is you will need to use Java 8 to build since msf4j is developed on Java 8. So you will need to run Identity Server on Java 8 as well. After building the project[2] please copy the jar inside target directory to $IS_HOME/repository/components/dropins/ directory. And then please add the following configuration to Identity.xml which is placed under $IS_HOME/repository/conf/identity/ folder inside tag OAuth . <IdentityOAuthTokenGenerator>com.wso2.jwt.token.builder.JWTAccessTokenBuilder</IdentityOAuthTokenGenerator> Then go to the database you used to store oauth tokens (This is the database pointed from the datasource you mentioned in the $IS_HOME/repository/conf/identity/identity.xml) and then alter the size of the column ACCESS_TOKEN of the tab

Oauth custom basic authenticator with WSO2 IS 5.1.0

WSO2 Identity Server supports Oauth2 authorization code grant type with basic authentication OOTB. But basic authentication is done only with WSO2 user store. So there could be use cases that basic authentication has to be done against some other system. In this case you follow below steps to achieve your requirement. First you need to create an class which extends AbstractApplicationAuthenticator and implements LocalApplicationAuthenticator. Because this class is going to act as your application authenticator so it needs to be an implementation of application authenticator interface and to achieve this it needs to be a local authenticator as well. [2] public class CustomBasicAuthenticator extends AbstractApplicationAuthenticator implements LocalApplicationAuthenticator {   Then you need to override the initiateAuthenticationRequest method so you can redirect to the page to enter user and password. In my sample I redirected to the page that is used by our default basic au

Installing gluster in AWS EKS

This article is a continuance of [1] . Purpose of this article is to document the steps, issues and solutions to those issues we have to face when installing gluster in EKS (Elastic Kubernetes Service). For gluster we need a disk to be attached with the K8s node. In EKS easiest way of implementing this is, adding it to the node configuration. So every time a node comes up, it comes up with a disk attached to the defined path. You can use this path in the topology.josn as mentioned in [1] . Next step is to install gluster using the gk-deploy script. The challenge comes here after. To use gluster in pods, you need to define a storage class. The heketi url mentioned in the storage class definition, should be accessible from master node. But the given heketi url is a cluster IP type k8s service. But in EKS deployments masters are managed by AWS and master don't have access to cluster IPs. So how we can solve this? Actually I tried to contact AWS support on this and I didn't got