For some reason Zipkin is using the Consul discovery name instead of the base spring.application.name property.
spring:
consul:
discovery:
prefer-ip-address: true
instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
But I want it to use the non-randomized application name (so myservice instead of myservice-67gg8d368).
If I set the Zipkin property zipkin.service.name then Consul throws errors saying it cannot find the service.
I'm unsure why the two are even sharing properties and not just adhering to their own. I'd like the service to use it's base application name because otherwise Zipkin is hard to use, as it lists every new container as a completely new service, making it very difficult to see over time how code changes have changed timing.
UPDATE:
This is the error I get in my logs if I set the zipkin.service.name
[o.s.c.c.d.ConsulDiscoveryClient] : Unable to locate service in consul agent: my-service-91828f2f88f18c3fadf193bfa3ad6d1f
Related
So I am new to metrics and micrometer. I am have followed this tutorial in which we set up some basics Meters like a counter and a Gauge and expose the metrics. I am able to see the metrics when I hit the endpoint /actuator/prometheus. I can seem my custom meters there.
So now I am trying to expose the metrics to datadog. I have imported the following dependency:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-datadog</artifactId>
<version>1.8.5</version>
</dependency>
and also have this on my application.properties file:
management.endpoints.web.exposure.include=*
management.metrics.export.datadog.apiKey=123
I am aware i have not included any url to data or any of that sort but i was under the impression that i could simply see the metrics im collecting via the actuator endpoint by accessing something like /actuator/datadog? Is my understanding correct? I essentially want to see the metrics im collecting before sending it out to datadog. Is this possible?
No, you can't see any metrics under /actuator/datadog since the metrics are pushed rather than pulled.
The usual approach used in a Spring Boot application together with Datadog is to send data out from the app is over UDP and utilizing the StatsD protocol for the message structure. You can achieve this by adding micrometer-registry-statsd to your dependency which will auto-configure the app.
Some config for Datadog:
management:
metrics:
export:
statsd:
enabled: true
flavor: datadog
defaults:
enabled: true
datadog:
api-key: 123456
How can you inspect the metrics before it is sent to datadog?
One way of doing this during development is to inspect the UDP messages, so basically spin up a UDP server on localhost and port 8125 (these are the default values but can be overridden).
I was in the same situation some time ago and wrote my own UDP server, you can see it here https://github.com/hcgoranson/UDP-server
I have a spring client application which is using a cloud server, I have a branch for each environment, for example, client STAG points to STAG branch in http://#giturl.So, what I'm trying to do is creating another branch called common which consists of common properties across the environment. I want to point STAG branch from client application to cloud server and as well as to common branch which retrieves all the common properties used across all the environments, Tried to use the composite type in a cloud server in application.yml by defining the same URL and different labels no luck on that any thoughts?
Tried using the composite type but didn't worked
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
-
type:
git:
uri: https://#gitURI
searchPaths: '{application}/,common/'
-
type:
git:
uri: https://#gitURI
searchPaths: '{application}/'
Ok, so you might to look at this part of the documentation and play with those 3 properties at the client app, where label would be the branch names in a comma separated string. The searchPaths property at the server's side would be {application} since that is the subfolder.
You might want to consider having multiple config repositories since that will be easier to manage.
Hope that helps! :)
How to map a URI to another URI in the application.yml of a spring-cloud-config server ?
I'm trying to deploy my spring-cloud-config-server application using Jenkins. I've defined the Git URL as <gitRepo>/{profile}-application.properties. Because I'm deploying the application without sending the profile, it is taking default as the profile and application is trying to reach <gitRepo>/default-application.properties which doesn't exist and therefore the health check on the application is failing as a part of the jenkins pipeline.
I now want to map URI : <gitRepo>/default-application.properties to URI : <gitRepo>/cit-application.properties.
Can this be done in the YML? I found many ways to only have multiple URIs based on the repositories, but that is not what I'm looking for.
spring:
cloud:
config:
server:
git:
uri: https://<gitrepo>/{profile}-configuration.git
pattern:
- '*/default-configuration'
uri: https://<gitrepo>/cit-configuration.git
we've disabled the health check by using
healthcheck:
enabled: false
That helped us resolve the issue.
Context
I'm developing a proof of concept with Spring Zuul and Eureka. I want Zuul to work as an API Gateway and I want it to discover my microservices registered in Eureka. I want my microservices to be versioned. Zuul, Eureka and each microservice run on their own (I have a separate project for all of them).
I'm using Spring Boot 1.5.3 and Spring Cloud Dalston. But I can upgrade, if necessary.
Now, let's say that I have one microservice configured in the following way in the application.yml:
spring:
application:
name: microservice-v1
server:
port: 11001
eureka:
client:
serviceUrl:
defaultZone: http://localhost:11000/eureka/
This microservice has a GET /microservice REST endpoint configured which I can access from the address http://localhost:11001/microservice. It runs well and it registers itself with Eureka.
This ZuulReverseProxy.java is the main class of my Zuul project:
#SpringBootApplication
#EnableDiscoveryClient
#EnableZuulProxy
public class ZuulReverseProxy {
public static void main(String[] args) {
SpringApplication.run(ZuulReverseProxy.class, args);
}
}
Based on the Spring Cloud Docs, I have this configuration class:
#Configuration
public class ZuulConfiguration {
#Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<version>v.+$)",
"${version}/${name}");
}
}
And this is the application.yml of my Zuul project:
spring:
application:
name: zuul
server:
port: 8888
zuul:
prefix: /api
strip-prefix: true
eureka:
client:
serviceUrl:
defaultZone: http://localhost:11000/eureka/
Zuul looks into Eureka, gets the list of registered microservices and creates a mapping for each one according to the PatternServiceRouteMapper above. I'm not ignoring any services for now.
All of the above, allows Zuul to redirect http://localhost:8888/api/v1/microservice/microservice to http://localhost:11001/microservice, for example. In a more general way, it redirects anything with the path /api/v1/microservice/<some-path> to http://localhost:11001/<some-path>
Question
How can I avoid writing microservice twice in the URL, but still be able to request the mapping /microservice in the controller of my microservice?
A solution to this problem could be requesting the mapping / instead of /microservice. But I don't want to do that. The reason is that I'm using Swagger and its Codegen to generate interfaces and if I request the mappings without writing a collection name, I feel that my specification is not as good.
I thought of writing a route Zuul filter, but I couldn't find a good example. Also, I think that if I could alter the code that handles the moment when Zuul tries to map the Eureka services to a path, that could be a solution.
When not in conjunction with Eureka, Zuul allows to specify an input path and a forward URL with address, port and something else. The same should be possible when specifying a Service Id. Maybe I can modify some code in a way that the routing is still dynamic but that I can add that something else.
Would modifying the classes SimpleRouteLocator or ZuulHandlerMapping help? or is another class in charge of that dynamic routing? Also what would be the best way of implementing something like this?
Edit
I realized that when you configure Zuul like this for example:
zuul:
add-proxy-headers: true
sensitive-headers: Cookie,Set-Cookie
routes:
uaa:
path: /uaa/**
service-id: oauth-v1
strip-prefix: false
sensitive-headers:
It does what I want it to do. That strip-prefix is different from the global one.
When I configured my Zuul that way, in the log I see:
... o.s.c.n.zuul.filters.SimpleRouteLocator : Matching pattern:/uaa/**
... : route matched=ZuulProperties.ZuulRoute(id=uaa, path=/uaa/**, serviceId=oauth-v1, url=null, stripPrefix=false, retryable=null, sensitiveHeaders=[], customSensitiveHeaders=true)
When Zuul loads the services registered in Eureka, in the log I see
.... o.s.c.n.zuul.filters.SimpleRouteLocator : route matched=ZuulProperties.ZuulRoute(id=v1/microservice, path=/v1/microservice/**, serviceId=microservice-v1, url=null, stripPrefix=true, retryable=null, sensitiveHeaders=[], customSensitiveHeaders=false)
The only significant difference is that the latter says stripPrefix=true and to solve my problem, it should be false.
I think that it should be possible to change that default behaviour somehow...
I cannot get database information or filesystem information to show up on the /health endpoint. I only can get:
{
"status": "UP"
}
Details about my setup and configuration:
- Spring Boot 1.3.3
- Running the WAR on JBoss EAP 6.4
- Datasource is a JNDI resource.
- Oracle is the database
spring:
datasource:
# Must match the datasource name in JBoss standalone.xml
jndi-name: java:jboss/beautiful-ds
driver-class-name: oracle.jdbc.driver.OracleDriver
jpa:
properties:
# escapes reserved words used as column names (if any)
globally_quoted_identifiers: true
show-sql: true
hibernate:
naming_strategy: org.hibernate.cfg.EJB3NamingStrategy
server:
servlet-path: /*
management:
health:
diskspace:
enabled: true
db:
enabled: true
endpoints.health.sensitive: false
One thing i found on /configprops is this, which I'm not sure whether it is related:
"spring.datasource.CONFIGURATION_PROPERTIES": {
"prefix": "spring.datasource",
"properties": {
"error": "Cannot serialize 'spring.datasource'"
}
I had tried adding "driver-class-name: oracle.jdbc.driver.OracleDriver" thinking it maybe needed more details, but that didn't change the situation.
so yeah, what gives? I made a vanilla example project which at least shows the filesystem stuff out the gate, so not sure why either don't want to show in my "real" app. Tell me your great and wise answers! :)
By default Spring sets the below property to never.
To be able to see full health details add the below property to your application.properties.
management.endpoint.health.show-details=always
From the spring-boot documentation:
45.6 Security with HealthIndicators
Information returned by HealthIndicators is often somewhat sensitive in nature. For example,
you probably don’t want to publish details of your database server to
the world. For this reason, by default, only the health status is
exposed over an unauthenticated HTTP connection. If you are happy for
complete health information to always be exposed you can set
endpoints.health.sensitive to false. Health responses are also cached
to prevent “denial of service” attacks. Use the
endpoints.health.time-to-live property if you want to change the
default cache period of 1000 milliseconds.
Make sure to have following properties set.
endpoints.health.sensitive=true # Mark if the endpoint exposes sensitive information.
management.health.db.enabled=true # Enable database health check.
management.health.defaults.enabled=true # Enable default health indicators.
management.health.diskspace.enabled=true # Enable disk space health check.
In cases if you are using spring security, then by default security is enabled for actuator endpoints, disable it in your yml file -
management:
security:
enabled: false
IIUC, the aggregate health is shown under /health, at least (IIUC) for springboot2. Meaning, that even if you have everything configured just right, only one line will be shown.
UPDATE: and if this is not what you need, you have to specifically ask to see details. Check these settings:
management.endpoint.health.show-details=when-authorized
management.endpoint.health.roles=ADMIN
You mixed YAML and Properties syntax in your configuration file. Replace the last line by the following, and it should work:
endpoints:
health:
sensitive: false