Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
586 views
in Technique[技术] by (71.8m points)

java - Spring Boot : Count Page Views - Actuators

I have a requirement to count the views on each endpoint. The idea is to create one common Request Count Mapping for all endpoints which should return the view count based on a dynamically entred endpoint.

Let's say someone wants to check the view counts on http://localhost:8080/user/101.

  1. RequestMappping path = /admin/count & RequestParam = url (Here /user/101)
  2. Then create the dynamic Request based on RequestParam http://localhost:8080/actuator/metrics/http.server.requests?tag=uri:/user/101
  3. Get and Return the Response of dynamic Request (JSON Object) and get the value of COUNT

I stuck on how to send a dynamic request to http://localhost:8080/actuator/metrics/http.server.requests?tag=uri:/user/101 and return the response of it and get the count value


@RequestMapping(path="/admin/count",method=RequestMethod.POST)
public JSONObject count(@RequestParam(name="url") final String url)//@PathVariable(name="url") final String url
{   
    String finalURL = "http://localhost:8080/actuator/metrics/http.server.requests?tag=uri:" + url + "";
    return sendRequestToURL(finalURL);  
}

@RequestMapping(path="/{finalURL}",method=RequestMethod.GET)
public JSONObject sendRequestToURL(@PathVariable("finalURL") String url)
{
    //How to return the response Here
}

This is what I get when Directly fire the URL

GET: http://localhost:8080/actuator/metrics/http.server.requests?tag=uri:/user/101

  {
    "name": "http.server.requests",
    "description": null,
    "baseUnit": "seconds",
    "measurements": [
        {
            "statistic": "COUNT",
            "value": 1
        },
        {
            "statistic": "TOTAL_TIME",
            "value": 0.3229436
        },
        {
            "statistic": "MAX",
            "value": 0.3229436
        }
    ],
    "availableTags": [
        {
            "tag": "exception",
            "values": [
                "None"
            ]
        },
        {
            "tag": "method",
            "values": [
                "GET"
            ]
        },
        {
            "tag": "outcome",
            "values": [
                "SUCCESS"
            ]
        },
        {
            "tag": "status",
            "values": [
                "200"
            ]
        }
    ]
}

Environment:

    `spring boot 2.1.2.RELEASE`
    <java.version>1.8</java.version>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So you want to encapsulate actuator/metrics with /admin/count

There are many ways and library for calling Rest API in Java

I will add the simplest one

Something like this

public JSONObject sendRequestToURL(@PathVariable("finalURL") String urlToRead)
{
      StringBuilder result = new StringBuilder();
      URL url = new URL(urlToRead);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setRequestMethod("GET");
      BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
      String line;
      while ((line = rd.readLine()) != null) {
         result.append(line);
      }
      rd.close();
      return new JSONObject(result.toString());  // org.json
}

Edit 1:

You are almost there. Just need to parse String to JSONObject. Try this maybe

String strJson = result.toString().replace(""","'");
JSONObject jo = new JSONObject(strJson.substring(1,json.length()-1));
return jo;

Edit 2:

I guess you have Spring Security in place.

And when you are calling an API internally, Spring is treating as an external call which requires Authentication.

As a workaround, you can exclude /actuator API from security context.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests()
     .antMatchers("/actuator*").permitAll()

     ...
}

or in XML

<security:http  auto-config="true"  use-expressions="true"   >
    <security:intercept-url pattern="/actuator*" access="permitAll"/>

    ...
</security:http>

And hopefully Spring security will ignore this URL and you will not get Login Form.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...