Trying to understand application logging best practice in a Kubernetes cluster - spring

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

Related

Dynamically change log levels across all instances

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

Best way to start multiple dependent spring boot microservices locally?

Currently my team maintains many spring boot microservices. When running them locally, our workflow is to open a new IntelliJ IDEA window and pressing the "run" button for each microservice. This does the same thing as typing gradle bootRun. At a minimum each service depends on a config server (from which they get their config settings) and a eureka server. Their dependencies are specified in a bootstrap.yml file. I was wondering if there is a way to just launch one microservice (or some script or run configuration), and it would programatically know which dependencies to start along with the service I am testing? It seems cumbersome to start them the way we do now.
If you're using docker then you could use docker compose to launch services in a specific order using the depends_on option. Take a look here and see if that will solve your problem.
https://docs.docker.com/compose/startup-order/

Deploy dockerized spring boot web on App Engine

I have a Spring Boot web application which is currently deployed Google App Engine. Now I am shifted to Docker and want to deploy the docker image of this application on to App Engine.
So far, I could not find any document related to this. Most of the documents explain how to deploy a docker image of Spring boot on Tomcat. Is there any way to achieve this?
First you need App Engine using the flexible environment , if you want deploy by docker image.
Here is the document Building Custom Runtimes.
A custom runtime allows you to use an alternate implementation of any supported App Engine flexible environment language, or to customize a Google-provided one. It also allows you to write code in any other language that can handle incoming HTTP requests (example). With a custom runtime, the App Engine flexible environment provides and manages your scaling, monitoring, and load balancing infrastructure for you, so you can focus on building your application.
In official case they have their sample DockeFile by jetty. But you can ignore the jetty part, just make your spring boot application executable ,and run it.
FROM gcr.io/google-appengine/jetty
ADD test-webapp-1.0-SNAPSHOT.war $JETTY_BASE/webapps/root.war
WORKDIR $JETTY_BASE
RUN java -jar $JETTY_HOME/start.jar --approve-all-licenses --add-to-startd=jmx,stats,hawtio
&& chown -R jetty:jetty $JETTY_BASE
Hopefully this helps:
https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/helloworld-springboot
One compelling benefit with Docker containers is that, when the containers works on one runtime (e.g. Tomcat), it should be relatively straighttforward to swap in a different runtime (e.g. App Engine).
NB App Engine Flexible is the specific service that you want. It is similar to App Engine Standard but it schedules containers for you.
The primarily requirement for a container (image) to work with App Engine Flexible is that the container expose an HTTP endpoint on port 8080. As long as your container meets this obligation, you can run anything within it.

Unable to link Spring boot application with Azure Application insight using application.properties, when logback.xml is used

I have created a spring-boot starter project and linked Azure Application insight to it. The properties like instrumentation- key is defined in "application.properties". On launching the application it is correctly linked to App Insight as can be verified by Live Metrics Stream.
However same application fails to connect to Azure App Insight if logback.xml is included in project (in resources), in this case to connect to App insight I have to include ApplicationInsights.xml as well.
But I do not want to use "ApplicationInsights.xml" in my application for 2 reasons. 1. I do not want multiple configuration files. 2. I am not able to inject key , i.e. not able to externalize key which might come as vm arguments or environment variable.
Defining InstrumentationKey and other configuration in application.properties works only when logback.xml is not present.
sample project (asset-register.zip) can be found at https://github.com/Microsoft/ApplicationInsights-Java/issues/710

best way to read a file in Spring Boot

I have a spring boot application that currently runs in embedded Tomcat. I have a file, states.csv, that I want to parse on startup and seed my states database table (I tried via liquibase but that refuses to work).
I put the file in resources/main/ and that appears to work fine. My question is, if I decided against embedded Tomcat in the future (say moving to AWS or a regular Tomcat), is this still the best location to keep files for use?
I don't want to code myself into a corner if there is a better way to do this.
This depends entirely on how you're reading the file. As long as you're grabbing it out of the classpath, you should be fine. (And I've run single-jar applications on both basic AWS VMs and Cloud Foundry on EC2 with no difficulty at all.)

Resources