Bucket4j not running, to rate limit api - spring

Pom.xml file
<groupId>com.giffing.bucket4j.spring.boot.starter</groupId>
<artifactId>bucket4j-spring-boot-starter</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>jcache</artifactId>
<version>2.8.2</version>
</dependency>
application-local.yml file
spring:
cache:
cache-names:
- rate-limit-buckets
caffeine:
spec: maximumSize=100000,expireAfterAccess=3600s
bucket4j:
enabled: true
filters:
- cache-name: rate-limit-buckets
filter-method: servlet
strategy: first
url: /patient
http-response-body: "{ \"status\": 429, \"error\": \"Too Many Requests\" }"
rate-limits:
- expression: getRemoteAddr()
bandwidths:
- capacity: 1
time: 30
unit: seconds
I have set the capacity to 1 and time to 30s so that I receive "Too Many Requests" error upon 2 api hits with in 30s, but I am not receiving any error or anything, basically bucket4j rate limiting is not even running as it seems.
Is my application-local.yml even being loaded? earlier I had the configurations in application-local.properties file and rate limiter was not working by that either, after exploring internet some people suggested using .yml file to load bucket4j configs so I did that too but even now it is not working.

Related

Monitoring Spring Security application with a bearer_tocken

I want to set up monitoring Spring Security application, which has updated bearer token.
I connect monitoring using a combination of Grafana and Prometheus, but after a token refresh time, it disconnects.
The Spring Security application implements a token refresh mechanism after authorization.
pom.xml dependensies:
<dependency>
<groupId>io.micrometer.prometheus</groupId>
<artifactId>prometheus-rsocket-spring</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Example of the prometheus config file I use:
scrape_configs:
- job_name: 'project_manager'
scrape_interval: 5s
bearer_token: 'my.bearer.tocken.example'
metrics_path: '/api/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8200']
I tried use this settings in application:
management.security.enabled=false
management.metrics.sensitive=false
Monitoring works successfully for an hour, after which the token is updated and the connection between Prometheus and the application is lost.
Perhaps I can set up a refresh token in the prometneus configuration?

Eureka is unable to find port when running spring boot on a random port

Following are the dependencies in my local:
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>2.13.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.properties
grpc.server.port=${PORT:0}
eureka.client.serviceUrl.defaultZone=http://localhost:8791/eureka/
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}
bootstrap.properties
spring.application.name=grpc-service
Eureka server is detecting port 8080 instead of the actual port used in the Eureka client. There are similar issues reported in the past, and it was fixed as per their developers. Did I miss anything on the above mentioned config?
Update
I modified my application.properties file with the below:
grpc.server.port=${PORT:0}
server.port=${grpc.server.port}
eureka.client.serviceUrl.defaultZone=http://localhost:8791/eureka/
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}
eureka.instance.non-secure-port-enabled=true
eureka.instance.secure-port-enabled=false
eureka.instance.non-secure-port=${server.port}
But now Eureka is not detecting the service at all.
I was able to solve this by making the below changes:
application.xml
eureka.instance.non-secure-port-enabled=true
eureka.instance.secure-port-enabled=false
server.port=${grpc.server.port}
eureka.client.serviceUrl.defaultZone=http://localhost:8791/eureka/
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}
eureka.instance.non-secure-port=${grpc.server.port}
grpc.server.port is passed as runtime argument. After making these changes, Eureka is now detecting the exact port used in Eureka clients.

How do you export metrics from a Spring Boot application into Prometheus?

I have a simple Maven Spring-Boot Application (Java) and am using Prometheus to collect metric information from it. I have all of the necessary Prometheus dependencies in my pom file, and I have included the #EnablePrometheusEndpoint annotation to my #SpringBootApplication class, but when I run my application and try to access the metrics on localhost:8080/prometheus (which I think is the default endpoint where Prometheus sends instrumentation metrics?), I get a 401 error. Did I instrument my application correctly such that metrics can be collected by Prometheus using the #EnablePrometheusEndpoint annotation? Where does Prometheus show my instrumented metrics (is it in localhost:8080/prometheus)? I've also tried looking for these metrics in localhost:8080/metrics, but no luck. Any help is greatly appreciated.
#SpringBootApplication
#RestController
#EnablePrometheusEndpoint
public class Example {
//Just a logger that keeps track of relevant information:
private static final Logger LOGGER = Logger.getLogger(Example.class.getName());
//counter for counting how many times an endpoint has been hit
static final Counter myCounter = Counter.build()
.name("CounterName") //note: by convention, counters should have "_total" suffix
.help("Total requests recorded by a specific endpoint")
.labelNames("status")
.register();
#RequestMapping("/hello")
String hello() {
myCounter.labels("customLabel1").inc(); //increment the number of requests by one
LOGGER.log(Level.INFO, "Number of times /hello has been hit: " + myCounter.labels("customLabel1").get());
return "Hello world! This is an example response!";
}
#RequestMapping("/homepage")
String homePage() {
myCounter.labels("customLabel2").inc(); //increment the number of requests by one
LOGGER.log(Level.INFO, "Number of times /homepage has been hit: " + myCounter.labels("customLabel2").get());
return "this is the home page!!";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Example.class, args);
}
}
Below is my pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Prometheus dependencies -->
<!-- The client -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_spring_boot</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_servlet</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Hotspot JVM metrics -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Exposition HTTPServer -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_httpserver</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Pushgateway exposition -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Spring Boot Actuator for exposing metrics -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
</dependencies>
</project>
And below is my prometheus.yml file, set (I think) to scrape my spring-boot app on localhost:8080 in the last few lines:
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'codelab-monitor'
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first.rules"
# - "second.rules"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
#The following lines are meant to monitor my spring boot app
- job_name: 'hello_world_spring_boot'
scrape_interval: 5s
static_configs:
- targets: ['localhost:8080']
This is what I see when I look at my prometheus dashboard, running on localhost:9090
Prometheus dashboard status 401 message
Your Prometheus is configured to look for metrics at http://localhost:8080/metrics (default) whereas #EnablePrometheusEndpoint exposes the metrics at http://localhost:8080/prometheus.
So, you should set metrics_path to prometheus in your prometheus.yml.
The 401 happens, because by default the metrics endpoint of Spring Boot Actuator is protected.
Try adding endpoints.prometheus.sensitive: false in your application.properties or manifest. This will make your prometheus endpoint unprotected and it will be available for scrape.
For publishing custom metrics into Prometheus, you need to use a Prometheus Pushgateway.
More documentation can be found on these two links
https://github.com/prometheus/pushgateway
https://prometheus.io/docs/practices/pushing/

monitoring spring boot service (actuator, security enabled) using prometheus

I am currently trying to use PrAG stack to monitor spring boot based microservices. Have 2 spring boot projects 1.5.4 (pom.xml) have the following dependencies configured to get the metrics and transform the metrics to prometheus server:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>com.moelholm</groupId>
<artifactId>prometheus-spring-boot-starter</artifactId>
<version>1.0.1</version>
</dependency>
Prometheus Scrape Configs:
scrape_configs:
- job_name: 'Test-springboot-actuator'
scrape_interval: 2s
metrics_path: '/prometheus'
static_configs:
- targets: ['localhost:8090']
- job_name: 'secondApp'
scrape_interval: 2s
basic_auth:
username: user
password: pass
metrics_path: '/prometheus'
static_configs:
- targets: ['localhost:8080']
Test project does not use spring security , but the secondAPP uses the spring security.
Second App requires the basic authentication. Prometheus pod does not start,it somehow does not read the credentials that have been set in scrape_config.
Can anyone point me to the right direction?
One thing you can do is allow the metrics endpoint to work when security is enabled. To do that you can use this setting.
endpoints.metrics.sensitive=false
Reference.

Spring Cloud Config Server and Client with RabbitMQ : Props not updated after git push

I am running Spring Cloud Config Server and a Cloud Config Client in Pivotal Cloud Foundry .
1st version:
I can update client properties by pushing a YML file to a git repo. I did a POST on config-client/refresh and it updated successfully. I am connecting via HTTPS.
2nd version:
I am now trying to automatically push config updates with RabbitMQ. My Cloud Config Server successfully receives a gitlab webhook POST call to the config-server/monitor endpoint. Config Server sees the update and sends a message to my Config Client.
However, the problem is that the client never updates its properties. I don't think it knows that any of its property files are updated. [ It may not know specifically what file was updated... ]
Is what I'm trying to do even possible with gitlab's webhooks ?
Thank you for any help.
Client log entries with app context reload highlighted. This happens after the code push:
2017-02-03T20:53:59.27-0500 [APP/0] OUT 2017-02-04 01:53:59.274 INFO 19 --- [nio-8080-exec-5] o.s.c.c.monitor.PropertyPathEndpoint : Refresh for: *
2017-02-03T20:53:59.34-0500 [APP/0] OUT 2017-02-04 01:53:59.346 INFO 19 --- [nio-8080-exec-5] nfigurationApplicationContextInitializer : **Adding cloud service auto-reconfiguration to ApplicationContext**
2017-02-03T20:53:59.35-0500 [APP/0] OUT 2017-02-04 01:53:59.358 INFO 19 --- [nio-8080-exec-5] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#3325da05: startup date [Sat Feb 04 01:53:59 UTC 2017]; root of context hierarchy
These are my dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus-parent</artifactId>
<version>1.3.0.M1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-monitor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

Resources