Spring Boot Actuator to show service start datetime - spring-boot

I am using spring-boot-starter-actuator in my project wanted to show service starts date time along with other information on /info end point.
Please guide how to achieve this.
Thanks in advance

/startup - is the Actuator Endpoint to see the startup information.
Sample URL syntax:
http://<HOST>:<port>/actuator/startup
For more info, visit here
--- Edit---
/startup endpoint does not get exposed by default, Hence need to enable explicitly by below property in application.properties :
management.endpoints.web.exposure.include=startup
BufferingApplicationStartup class is in-memory buffered implementation for capturing startup steps. Hence in the main class below changes are required:
import java.util.TimeZone;
import javax.annotation.PostConstruct;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
#SpringBootApplication
public class ActuatorEndpointApplication {
public static void main(String[] args) {
// SpringApplication.run(ActuatorEndpointApplication.class, args);
SpringApplication app = new SpringApplication(ActuatorEndpointApplication.class);
app.setApplicationStartup(new BufferingApplicationStartup(2048));
app.run(args);
}
}
Now test the url:
http://<HOST>:<port>/actuator/startup in Chrome/Postman.
For more info, refer here

Related

Error Messages as Key Value Pairs - from a Properties File in classpath - Spring boot 2.0

We are currently on a Spring Boot Version 1.x
We have Error Messages (Error Key -> Error Code) pairs in our error.properties file (this is in the class path).
We leveraged PropertiesConfigurationFactory to get these Error Key and Error Code pairs in to a POJO, this POJO had a Map
Hence very convenient to be used across our application to get an Error code for a given Error Key.
What is its equivalent in Spring Boot 2.x ?.
Assuming you have error.properties file with the below contents:
errors.error1=101
errors.error2=102
errors.error3=103
A simple spring boot app that demonstrates the injection of these properties :
package snmaddula.remittance;
import java.util.Map;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
#SpringBootApplication
#ConfigurationProperties
#PropertySource("classpath:error.properties")
public class DemoApplication {
private Map<String, Integer> errors;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public CommandLineRunner cli() {
return (args) -> {
System.out.println(errors); // you can print and see the error properties injected to this map.
};
}
public void setErrors(Map<String, Integer> errors) {
this.errors = errors;
}
}
With the use of #PropertySource and #ConfigurationProperties we can enable property injection provided we have a setter method for our attribute.
When you run this program, you can see the properties getting printed on to the console as I added a CommandLineRunner cli() {..} to show the working of it.
The working sample is available on GitHub.

Spring Boot REST API not reachable in GCP

I am deploying the Spring Boot Rest API in Google Cloud Platform. The Rest API is running fine in my local while running the application as Spring boot application. But the same REST API URL is not recognized while deploying in GCP.
Project Structure:
app.yaml:
runtime: java
env: flex
runtime_config:
  jdk: openjdk8
handlers:
- url: /.*
script: this field is required, but ignored
GreetingController.java
package com.designdreamers.rest.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.designdreamers.rest.vo.Greeting;
#RestController
public class GreetingController {
private int idValue;
#RequestMapping(value="/greet")
public Greeting greeting(#RequestParam(value="content", defaultValue = "Hello World!!")String content){
Greeting greeting=new Greeting();
greeting.setId(idValue++);
greeting.setContent(content);
return greeting;
}
}
Application.java
package com.designdreamers.rest.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages = "com.designdreamers.rest.controller")
public class Application {
public static void main(String args[]){
SpringApplication.run(Application.class,args);
}
}
Below is the REST API response that I get on running the application as Spring boot application in local.
URL :http://localhost:8080/greet
{"id":1,"content":"Hello World!!"}
I deployed the same application in GCP and on hitting the REST API URI, below is the error that we get.
URI: http://helloworld-001.appspot.com/greet
Error: Not Found
The requested URL /greet was not found on this server.
A helping hand on identifying the issue would be very helpful.

Hystrix Dashboard Issue in Spring Boot

I am new to Hystrix Dashboard. I have written sample application with Hystrix.
I want to see the Hystrix chart (command metric stream). But I am getting the below error:
Circuit: Unable to connect to Command Metric Stream
Thread Pools: Loading...
I am using STS with Maven.
Below is the code used:
Simple server microservice application (Spring boot web running in port 8085)
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
#SpringBootApplication
public class BookstoreApplication {
#RequestMapping(value = "/recommended")
public String readingList(){
return "Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)";
}
public static void main(String[] args) {
SpringApplication.run(BookstoreApplication.class, args);
}
}
Simple client microservice application (Spring boot web running in port 8095) I have included the dependency of Hystrix and Hystrix Dashboard along with Web, so all the Hystrix dependencies are in classpath
package hello;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
#Service
public class BookService {
private final RestTemplate restTemplate;
public BookService(RestTemplate rest) {
this.restTemplate = rest;
}
#HystrixCommand(fallbackMethod = "reliable")
public String readingList() {
URI uri = URI.create("http://localhost:8090/recommended");
return this.restTemplate.getForObject(uri, String.class);
}
public String reliable() {
return "Cloud Native Java (O'Reilly)";
}
}
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.web.client.RestTemplate;
#EnableHystrixDashboard
#EnableHystrix
#EnableCircuitBreaker
#RestController
#SpringBootApplication
public class ReadingApplication {
#Autowired
private BookService bookService;
#Bean
public RestTemplate rest(RestTemplateBuilder builder) {
return builder.build();
}
#RequestMapping("/to-read")
public String toRead() {
return bookService.readingList();
}
public static void main(String[] args) {
SpringApplication.run(ReadingApplication.class, args);
}
}
By running the above code, the hystrix is working fine, when the BooKStoreApplication is down, it is going to fallback method.
Both the urls are working fine.
Normal Case:
http://localhost:8085/recommended
Output: Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
http://localhost:8095/to-read
Output: Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
When BookStoreApplication is down (http://localhost:8085/recommended) accessing http://localhost:8095/to-read returns "Cloud Native Java (O'Reilly)" as expected.
But when I tried to invoke this url http://localhost:8095/hystrix, I am getting the Hystrix DashBoard Page and asking for the stream value.
I have tried given http://localhost:8095/ or http://localhost:8095/to-read, and clicked "Monitor Stream" and it is going to next page with error:
Circuit: Unable to connect to Command Metric Stream
Thread Pools: Loading...
I've experienced the same. The main problem was, that I didn't have the actuator dependency in my maven pom. So I could not get the hystrix stream.
Include the spring-boot-actuator.
Check if localhost:8085/health is running.
Try to enter localhost:8085/hystrix.stream to stream value in Hystrix Dashboard.
Execute the service few times -> the dashboard should show the monitored method/command.

how to use the ApplicationArguments in spring-boot

I am learning the Spring-Boot(I am new to it), reading the Spring Boot Document. In the 23.6 Accessing application arguments, It talk about the ApplicationArguments, and the code is:
package com.example.project;
import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;
import java.util.*;
#Component
public class MyBean {
#Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
System.out.println(debug);
System.out.println(files);
}
}
It says if run with "--debug logfile.txt" debug=true, files=["logfile.txt"].
But in my project, I don't know how to run it. I create the spring-boot using Maven: The Project Structure
In Spring Boot doc ApplicationArguments is autowired in a bean. Here is a more hands on example where it's used in a Main method.
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args).stop();
}
#Override
public void run(ApplicationArguments args) throws Exception {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
System.out.println(debug);
System.out.println(files);
}
}
Assuming that you have an Application class with annotation #SpringBootApplication like in the answer provided by a.b.d.
To be able to provide the arguments within IntelliJ IDEA environment you will need to first Run the main method and then Edit 'Run/Debug Configurations' and under Main Class fill Program arguments field with "--debug logfile.txt":
In one word like a thousand :
the 'Program arguments' in your IDE field prefixed by -- is simply the same name as the 'Option' expected in the 'ApplicationArguments'.
Hence you can match --debug and "args.containsOption("debug")".

Spring Boot overriding YML profile from Command Line

I wan't to override an existing YML file profile using command line, so I did this.
Created a folder and added to the classpath
Copied another application.yml in that new folder
Ran this command mvn spring-boot:run -Dspring.profiles.active=unit-test
but it still picking up the "default" active profile from the source code application.yml. I also tried creating a application.properties instead of application.yml but it still didn't get picked up?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class SuchApplication implements CommandLineRunner {
#Autowired
private DogeService dogeService;
#Override
public void run(String... args) {
System.out.println("AutoConfiguration should have wired up our stuff");
System.out.println("Let's see if we are doge-worthy...");
if (dogeService.requiresDogeness()) {
System.out.println(dogeService.leDoge());
} else {
System.out.println("No Doge for us :(");
}
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SuchApplication.class, args);
}
}
I have the following YML file under my resources folder
spring:
profiles.active: default
---
spring:
profiles: default
doge:
wow: 10
such: so
very: true
---
spring:
profiles: unit-test
doge:
wow: 4
such: so
very: true
I had a similar problem with Spring Boot and resolved it with this annotation in my configuration class...
#PropertySource("classpath:application.yml")
But from the official Spring documentation, this annotation looks unnecessary, which is why I did not add on the first attempt.

Resources