Dynamically change log levels across all instances - spring-boot

Let's say, I have a spring boot application where I am using Log4j for logging.
In there, I want to change the log level dynamically without staring the whole application.
This can be achieved by exposing some endpoint to set the levels.
But, at production level, there might be multiple instances of the same application running across different servers.
So, how can we set the logging levels dynamically across all the container instances running the applications which are managed by kubernetes?

If your application read log levels from application.properties or application.yaml, ConfigMap would do it:
A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume
A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable.
You can check my other answer where I wrote step by step with explanation how to use a ConfigMap

Related

Trying to understand application logging best practice in a Kubernetes cluster

Considering a K8s cluster has 3 pods, each has a docker container of same SpringBoot app providing web services, with LogBack as logging solution.
Log path for each Spring Boot app is the same, and each application will do the same file logging, defined in application.properties. I wonder if without any volume configuration, is it going to cause locking situation so that each Spring Boot app will try to write to the same file at same time?
If above speculation is true, what is the best practice? Below is what I can think of
Create different volume for each pod so logging file write to different physical location. I think it is an overkill for logging
Generate unique file name suffix so app log file name for each application is different. Simply can be just cut off of pod name. However this solution requires to pass dynamic parameters to the pod -> container -> application

How do I load AWS region specific properties from Spring Boot application properties?

My java microservice (developed in Spring boot) loads S3 bucket from an application properties file. S3 bucket names for 4 different AWS regions are different (bucker-east-1, bucker-west-2 etc) hence how do I load AWS region-specific properties from application properties? For example, for us-west-2 region, bucker-us-west-2 property should be loaded, etc. is there any existing support for this type of feature in SPring boot?
There's at least a couple of ways you could handle this.
Use environment variables: Using env variable in Spring Boot's application.properties
Feasibly you could structure the names to be something like bucket.name=<bucket-prefix>-${AWS_REGION}
Use Spring profiles. You can create separate properties files for each region.
For example, you'd have application-us_east_1.properties, application-us_east_2.properties. You then can add the appropriate spring profile upon deployment by passing in the JVM parameter, -Dspring.profiles.active=us_east_1 to activate us_east_1. Alternatively, you can use the SPRING_PROFILES_ACTIVE environment variable similarly.

Spring Boot Managing Properties File

I am trying to revamp my microservice to maintain a single application yaml rather maintaining multiple profiles. Initially I was maintaining different profiles and the common configurations were repeated across the helm environment specific values yaml. Now the strategy is to move everything to values.yml and maintain environment specific values in config map. The problem I face is my application yml now looks very generic with placeholders and for the same reason the test runs fails as I cannot give a default value for each of the configurations in application.yml. The reason being, For Eg: mongodb cluster endpoint format is different in local to other environment. I managed to place a local specific yaml file under test/resources, but not sure it's the right approach. I need to anyway maintain a local specific yaml under main/resources for running locally. So essentially I am duplicating it under test resources as well. Is there any better way of pointing test to load the application-local.yml under main resources so that I can avoid the duplication or is there any better way of doing this as a whole?
1. Working with multiple configs in One File
You can add all your configurations in one property file as illustrated below
spring.application.name: test. ## Used for all profiles
---
spring.config.active.on-profile:dev
spring.database.host: localhost
spring.database.name: testing
---
spring.config.active.on-profile:prod. ##You can use spring.profiles:prod
spring.database.host: localhost
spring.database.name: testing
---
--- marks where yml document splits, while #--- marks where properties file splits.
Multi-document property files are often used in conjunction with the following activation properties
spring.config.activate.on-profile
spring.config.activate.on.on-cloud-platform
All property definitions defined without specifying the profile name are used on all profiles. In the above case spring.application.name will be used on all profiles dev or prod.
When running the application you can manually specify profile or you can set in within the yml or properties on properties that are used throughout the application.
spring.application.name: test
spring.profiles.active: prod
2. Testing your application
when running tests that need to access properties in yml(property)file there is
no need to redefine your configurations.Just add #ActiveProfile("profile-name")
on your tests.
for example:
#ActiveProfiles("dev")
#SpringBootTest(webEnvironmentSpringBootTest.WebEnvironment.RANDOM_PORT)

Is it possible to configure spring.cloud.config to use multiple bootstrap.yml files

I am mounting multiple volumes into my pod, each being a configMap that contain different pieces of what would fully construct Spring Cloud bootstrap.yaml file. For example, one configMap may contain the config server URI, and the second configMap may contain overrideSystemProperties property. These configMaps are laid down in files with different names (or with the same name but in different paths) in the pod. My question is is it possible to configure Spring Cloud to use multiple bootstrap.yaml files? I know one can configure Spring to look for additional properties in different locations using spring.config.additional-location. Is it possible to do the same with Spring Cloud bootstrap?

Loading multiple Profile based properties inside custom folder using Spring-Config Cloud Server

I am new to spring boot, have come across a situation...
l have 10 different property files based on various logical modules of a monolith application(db.properties,jms.properties, etc) and 7 envs(pre, sit1,sit2,uat1,uat2,prod, dr). The idea of having diffrent property files so that we can use them almost with no change whenever we move to microservice based approach.
One approach says - we use various spring application names
like - spring.application.name=db,jms,a,b .....
In this way we will land up having 10×7 = 70 files under same folde? (In order to make it profile driven) like jms.properties,jms-dev.properties,jms-uat.propetris...... for all various logical modules.
Is there any better approach to host the files using config server?
We have a monolith application and we plan to continue the same for the time being.
I am struggling to build such facility using spring cloud config server...if any one can help

Resources