Configuring SpringBoot 2 application for Micrometer for AWS cloudwatch - spring-boot

I have a springboot 2 application, and I want to display metrics in AWS Cloudwatch.
I have included micrometer cloudwatch dependency in pom.
Here setting is documented for various metric systems but not cloudwatch.
Whar else configurations I need to do for cloudwatch?

First of all you may have to add some additional dependecies. I needed the following:
org.springframework.boot - spring-boot-starter-actuator
org.springframework.cloud - spring-cloud-starter-aws
io.micrometer - micrometer-core
io.micrometer - micrometer-registry-cloudwatch
Boot was not able to manage the versions for these dependencies except for actuator in my case, so you might have to figure out the right versions for you.
Firthermore some application properties have to be set:
# disable unwanted features to prevent autoconfigure which will produce errors and abort of application startup eventually
# alternatively you can try to configure those features correctly if you intend to use them
cloud.aws.stack.auto=false
# enable micrometer for cloudwatch (only where there is actually access to it)
management.metrics.export.cloudwatch.enabled=true
# set the namespace that will contain the metrics for this application
management.metrics.export.cloudwatch.namespace=test
# set max batch size to the actual maximum (if not a bug in certain versions of micrometer for cloudwatch will send
# batches that are too big)
management.metrics.export.cloudwatch.batchSize=20
The next step will be in AWS. The role associated with your EC2-instance (or whatever you are using) needs to have the permission CloudWatch:PutMetricData.
Using this configuration should enable CloudWatch-Monitoring for your Spring-Boot-Application.
One of the sources I encountered stated that you should use:
cloud.aws.credentials.instanceProfile=false
This will prevent Spring Boot from automatically obtaining credentials that are necessary to push metrics to CloudWatch. You could also provide own credentials another way, but I didn't try that.

Related

Log4j Vulnerability (CVE-2021-44228) on Google Cloud Platform and PCF

Currently there are so many suggested steps that have been posted for excluding log4j-core library from dependency or upgrading to the latest (above version 2.15) version according to Spring Blog . Are there any recommended tools that can be used for protecting spring application deployed in Google App Engine or Pivotal Cloud Foundry(PCF) for protecting instead of patching them for redeployment?
Another necessary question is, does it make my application(microservice spring application) to be vulnerable if it uses another microservice for some of its service if it depends on another microservice and if that microservice already uses vulnerable version of log4j-core?
In regard to your first question, you can set an environment variable in order to disable the replacement lookups in log4j:
LOG4J_FORMAT_MSG_NO_LOOKUPS=true
Please note that this only works for log4j >= 2.10.
I believe you can set environment variables in PCF without having to redeploy the service (of course, a restart would be needed), so no new release would be needed. See: https://docs.pivotal.io/pivotalcf/2-3/devguide/deploy-apps/environment-variable.html and https://cli.cloudfoundry.org/en-US/v6/set-env.html
In order to see whether your spring-boot application is vulnerable to the exploit, you could use a spring-boot test I created for that purpose: https://github.com/chilit-nl/log4shell-example - You could test your application with and without the environment variable, to see if it has any effect (assuming that your application currently is vulnerable).
Short answer to your first question is may be. You can protect your application/service by using rules in WAF to discard the ${jndi://ldap pattern. However, there are so many mutations of this (base64 encoding etc.) that it will not be foolproof. If you are worried about dependencies, you should set the JVM Parameter and redeploy your app to prevent the lookup as a workaround.
Regarding your 2nd question - the answer is yes if the the 2nd micro service is being passed the same input and it's logging.

Secure some keys in application.properties - spring boot application

I have a spring boot application where I am using some aws services.
The code in openly available in Git.
I don't want to commit AWS secret and access keys which are part of application.properties. I can't add to .gitignore as I want to commit other values of application.properties.
Many are committing to this repo. We are adding these aws keys in local and making sure its not added as part of any commit.
I want to make sure the aws keys in application.properties should not come to git at any cost. Which is the best way to manage these secret keys.?
You shouldn't be placing AWS API keys in application.properties at all. If the application is running on AWS it should be using the IAM role of the server it is running on. If it is not running on AWS it should probably be using environment variables.
Please review the documentation on this subject here.
Thanks to #Mark B. I would prefer using Java system properties as we can maintain them at application level. Env variables will be at system level which is not really needed and it may lead to conflicts.
while running an spring-boot jar with mvn, it can be done as below
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Daws.accessKeyId=XXXXXXXXXXX -Daws.secretKey=XXXXXXXXXXX"
if running for IDE like Eclipse or IntelliJ, it should be added as VM Options.
-Daws.accessKeyId=XXXXXXXXXXX -Daws.secretKey=XXXXXXXXXXXX
After this AWS client object can be built as usual.
As an example,
SNS client can be build by
AmazonSNS snsClient = AmazonSNSClient.builder().withRegion(Regions.US_EAST_1).build();
SES client can be built by
AmazonSimpleEmailService emailClient = AmazonSimpleEmailServiceClientBuilder.standard().withRegion(Regions.US_EAST_1).build();

How to configure Micrometer's monitoring system at runtime with Spring Boot

I'm new to metrics in general and especially Micrometer, so this might be a dumb question:
Micrometer describes itself on the home page as a "facade" "without vendor lock-in", "think SLF4J, but for metrics". With "built-in support for [...] Netflix Atlas". The docs say it's included in Spring Boot 2.
So what I'd expect is the ability to configure the monitoring system on start-up - just as I would with SLF4J. So this doc describes a setting management.metrics.export.atlas.enabled (among others) for Spring Boot. But even with this setting auto-wiring a MeterRegistry registry fails as follows:
Parameter 4 of constructor in [snip] required a bean of type 'io.micrometer.core.instrument.MeterRegistry' that could not be found.
Action:
Consider defining a bean of type 'io.micrometer.core.instrument.MeterRegistry' in your configuration.
Google led me to Baeldung where I read about some micrometer-registry-atlas dependency plus providing a MeterRegistrybean of type AtlasMeterRegistry. This works, but it's not what I call a "facade without vendor lock-in", but I guess I'm just doing it wrong?
How can I provide the monitoring system during runtime, switching between Atlas and any other without re-compiling?
#crusy you are actually right, but the feature is part of the Actuator module. This is not well documented and I was lucky to find the answer in the Spring Boot Gitter channnel https://gitter.im/spring-projects/spring-boot/archives/2019/01/24?at=5c4980b00721b912a5cdc02f.
You will notice that the Metrics section in the Spring Boot documentation is under Actuator: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready-metrics.
This means that in order for Micrometer to work out of the box, you need to include Actuator in your build. E.g for Gradle:
implementation ('org.springframework.boot:spring-boot-starter-actuator')
The MeterRegistry bean will be there now.
One of the definitions I found on Wikipedia says that vendor lock-in:
makes a customer dependent on a vendor for products and services,
unable to use another vendor without substantial switching costs.
Micrometer helps to unify interfaces to collect metrics (timers, gauges, counters, etc.), but there is no standard on how these metrics are shipped to backends (Atlas, Prometheus, etc.). That is the main reason why you need to define a specific library (micrometer-registry-atlas), properties, and sometimes also additional configuration.
Micrometer doesn't bring costs needed to switch to another backend to zero, but at least they are kept to minimum.

springboot admin: How to display custom metrics in springboot admin GUI ("Metrics" tab)

We are using serveral microservices with springboot (Vers. 1.4.3) and for monitoring them springboot-admin (Vers. 1.5.0).
Inside our microservices we generate several custom metrics (using the
'#com.codahale.metrics.annotation.Timed' annotation).
While all these custom metrics are displayed through the ordinary actuator-endpoint "/metrics" they are sorrowly not shown in the springboot admin GUI -"Metrics" tab.
Obviously only "counter." and "gauge." metrics are displayed in the latter.
Is there any possibility to configure / modify springboot admin, so that these custom metrics also are shown - either in the existing 'metrics' tab or in another new tab ?
Ok, meanwhile I found out, that the new springboot-admin version 1.5.2 will solve our problem:
As I could see at a project from a colleague, this springboot-admin version will display ALL metrics without any restrictions regarding the metrics-key.
[ At the moment we can't upgrade to this version since our springboot-version dependency prevents it but in the future we'll be able to do so.]
So the problem is more or less solved.

Logback with Spring Boot - programatically change configuration at runtime to add Syslog Appender

I am building an application (Spring Boot 1.4.2) where i would like to offer an administrator the option to enable syslog but i want to avoid him/her having to manually edit any config files - in this case logstash-spring.xml.
Therefore i am trying to understand how i can achieve using a logback-spring.xml file as a baseline (e.g. define file based log options, levels etc. - settings i dont want the administrator to change) and on top of that provide a functionality at runtime where an administrator can add or change a syslog appender.
I have listed what i see as requirements:
The changes made to the Logger should be persisted after the Spring Boot application is restarted.
Ideally the syslog server info (name, port) are kept in my persistence layer (H2, hibernate) but i am not sure if that is possible as i guess the logging framework is being injected prior to my persistence layer?
The syslog appender that i want to add should be referenced by root logger so that all the packages i have configured logging for would go to syslog (not sure if this is just "how it works per default")
Also i dont know if i could simply treat logback-spring.xml as a regular XML object and use for example JAXB to manipulate that file and use the autoscan feature of Logback to simply read in the new changes?
I have played around with defining a Logger #Bean:
#Bean
public Logger logger() {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
// excluded implementation
}
This is being picked up by Spring Boot but that brings me to the 2 items i have listed above that i dont know how or where i would store the syslog server information the administrator would provide.
UPDATE:
I wrote the following which meets the 3 requirements above however i would appreciate any feedback on the actual implementation as i am very new to Spring and Java.
GitHub repository with implementation - spring-boot-logback-syslog
I managed to use the example i posted in my Github repo in my designated application and with that i am answering my own questions based on the implementation in that repo.
Please refer to the README for full details on how it was implemented.
UPDATE: As part of Spring Boot 1.5.1 there is an actuator that can set the logging level during runtime: Production Ready Loggers
Not necessarily 100% related to this topic but this was one of the requirements i had for the implementation as well as changing syslog related settings.

Resources