-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Add Eureka Service Discovery #3369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks! Unless something has changed, we still have a moratorium (instated a couple of months ago) for accepting any new SD mechanisms into Prometheus itself at the moment. The reason was that we have too many mechanisms already that are not well-tested, not well-understood, and have too few maintainers for them. We started efforts to introduce integration testing and more documentation (parts of the docs have already happened at least). But I think we still are not accepting new mechanisms into Prometheus proper at this moment. Instead, we would recommend running this outside via the File SD for now and consider it for integration into Prometheus later. @brian-brazil @cstyan @gouthamve @fabxc Am I correct that this is still the current state? |
Yes, that's the current state. From a very brief look, I believe this PR is also hardcoding organisation-specific assumptions. |
@juliusv - running for example Eureka via SD file is usually not possible in cloud environment where all services are stateless and you cannot mount a file system and share files between Prometheus and bridge application. |
is there any chance to have anyone to take care of this? Would like to have it since we are using netflix oss for our microservices stack |
there is also a discussion for http vs sd to it would be useful get some input regarding this use-case |
Until this is merged and released, there is another option to integrate Prometheus with Eureka. I have written an adapter that you can deploy with your Eureka instance. This adapter provides several HTTP endpoints that return information of the registered services and are compatible with the Prometheus' Consul discovery client (consul_sd_config). I have tested it for a couple of month now and it works great. I have put it up on Github: https://github.com/twinformatics/eureka-consul-adapter Feel free to give it a try (and feedback). |
due to lack of man power to review and maintain new SD we are on permanent hold for adding new SD. As a replacement we have now added an example how to implement a custom SD adapter that converts any SD to json file that can be used by the file SD |
@kangwoo are you still interested in this? I would like to investigate and see how we can integrate this work in Prometheus. |
yes. How can I help you? |
@kangwoo rebasing off master, dealing with any merge conflicts, and ensuring that all tests still pass would be a good place to start :) |
Maybe also see if we can move back to your forked client to upstream. |
Ok. I'll start working. |
0fe0dcb
to
a2ad803
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updating this. Unfortunately I don't know enough about Eureka to do a full review.
@@ -0,0 +1,112 @@ | |||
// Copyright 2016 The Prometheus Authors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, the copyright year for files you're adding should be 2020
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will change it.
discovery/eureka/client_test.go
Outdated
defer ts.Close() | ||
|
||
apps, err := fetchApps(context.TODO(), []string{ts.URL}, &http.Client{}) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use testutil.Ok(t, err)
to fail if an error was returned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change it to testutil.
discovery/eureka/eureka_test.go
Outdated
} | ||
) | ||
tgs, err := testUpdateServices(client) | ||
if err != errTesting { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can use testutil package in this file
docs/configuration/configuration.md
Outdated
[ refresh_interval: <duration> | default = 30s ] | ||
``` | ||
|
||
By default every app listed in Marathon will be scraped by Prometheus. If not all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
marathon -> eureka?
Could you squash all the commits into one, so we start fresh? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added some initial comments.
discovery/eureka/eureka.go
Outdated
appInstanceStatusLabel = metaLabelPrefix + "app_instance_status" | ||
appInstanceIDLabel = metaLabelPrefix + "app_instance_id" | ||
appInstanceMetadataPrefix = metaLabelPrefix + "app_instance_metadata_" | ||
appInstanceMetadataPresentPrefix = metaLabelPrefix + "app_instance_metadatapresent_" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can metadata be present and empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I need it. I will delete it.
discovery/eureka/client.go
Outdated
const appListPath string = "/apps" | ||
|
||
func fetchApps(ctx context.Context, servers []string, client *http.Client) (*Applications, error) { | ||
url := randomAppsURL(servers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems a very strange pattern. I would just limit that to ONE server and let the user put load balancing in front if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but generally Eureka customers implement and use client load balancing devices. I'll think about a better way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that really how the java client works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that really how the java client works?
If the request fails, change the server address and try again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that the users who would want that in prometheus could just have multiple eureka_sd_configs in the same job, with one server each,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will change it to limit it to ONE server.
discovery/eureka/client.go
Outdated
resp.Body.Close() | ||
}() | ||
|
||
if (resp.StatusCode < 200) || (resp.StatusCode >= 300) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resp.StatusCode / 100 == 2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
discovery/eureka/client.go
Outdated
}() | ||
|
||
if (resp.StatusCode < 200) || (resp.StatusCode >= 300) { | ||
return nil, errors.Errorf("non 2xx status '%v' response during eureka service discovery", resp.StatusCode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be more specific that %v, e.g. %d.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
discovery/eureka/eureka.go
Outdated
} | ||
|
||
// Remove services which did disappear. | ||
for source := range d.lastRefresh { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is that needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the application restarts, it may get out of Discovery.
To avoid immediate removal from the monitoring target if removed from the Discovery.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a correct behavior from the Prometheus perspective. Can you remove this, + lastRefresh?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. I will remove it
Class string `xml:"class,attr" json:"@class"` | ||
} | ||
|
||
func (s *MetaData) MarshalXML(e *xml.Encoder, start xml.StartElement) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would we need to marshal to xml?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need a marshal. I will delete it
return nil | ||
} | ||
|
||
func (s *MetaData) MarshalJSON() ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need XML or json, not both,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will delete json.
Add Eureka Service DiscoveryA example scrape configuration for running Prometheus on a Eureka
MetdataYou can use Eureka's application instance metadata.If you are using SpringBoot, you can add metadata using eureka.instance.metadataMap like this:
Example relabel to scrape only application that have "prometheus.scrape = true" metadata.
Example relabel to customize metric path based on application "prometheus.path = " annotation.
Example relabel to scrape only single, desired port for the application based on application "prometheus.port = " metadata.
|
Why did you close this? |
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
Signed-off-by: kangwoo <kangwoo@gmail.com>
discovery/eureka/eureka.go
Outdated
appInstanceVipAddressLabel: lv(t.VipAddress), | ||
appInstanceSecureVipAddressLabel: lv(t.SecureVipAddress), | ||
appInstanceStatusLabel: lv(t.Status), | ||
appInstancePortLabel: lv(strconv.Itoa(t.Port.Port)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Port and SecurePort are pointers, what happens if they're nil?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add a nil check.
Signed-off-by: kangwoo <kangwoo@gmail.com>
discovery/eureka/eureka.go
Outdated
@@ -162,21 +162,27 @@ func targetsForApp(app *Application) []model.LabelSet { | |||
model.AddressLabel: model.LabelValue(targetAddress), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
targetAddress := net.JoinHostPort(t.HostName, strconv.Itoa(t.Port.Port))
This should also check for nil.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I will check nil.
Signed-off-by: kangwoo <kangwoo@gmail.com>
@@ -157,10 +157,14 @@ func targetsForApp(app *Application) []model.LabelSet { | |||
|
|||
// Gather info about the app's 'instances'. Each instance is considered a task. | |||
for _, t := range app.Instances { | |||
targetAddress := net.JoinHostPort(t.HostName, strconv.Itoa(t.Port.Port)) | |||
var targetAddress string | |||
if t.Port != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we then use 80 as port? or not add the port to the address? @brian-brazil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There has to be an address label. This hasn't come up before, I'd suggest just hardcoding to 80 for now.
Signed-off-by: kangwoo <kangwoo@gmail.com>
```yaml | ||
# The URL to connect to the Eureka server. | ||
server: <string> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you miss the http client documentation (token file etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add http client options to documentation
Signed-off-by: kangwoo <kangwoo@gmail.com>
👍 |
Thanks @kangwoo !! |
Thank you everyone. |
Added Eureka Service Discovery.
The Eureka client used a 'https://github.com/kangwoo/go-eureka-client' library