microsoft / ApplicationInsights-Java

Application Insights for Java
http://aka.ms/application-insights
Other
295 stars 198 forks source link

How to define the cloud_RoleName in the Spring Boot 2 application? #632

Closed ifle closed 6 years ago

ifle commented 6 years ago

How to define the cloud_RoleName in the Spring Boot 2 application? We would like to sharing a single Application Insights resource with several micorservices

tomaszglinski commented 6 years ago

Need that too!

dhaval24 commented 6 years ago

@ifle thanks for asking the question. I think you can do this in the following way :

telemetryClient.getContext().getTags.put(ContextTagKeys.getKeys().getDeviceRoleInstance(), roleInstance)

You can do this same logic by creating your own context initializer by extending the Interface of the SDK called ContextInitializer.

By default the DeviceInfoContextInitializer sets the DeviceRoleInstace -> InetAddress.getLocalHost().getCannonicalHostName();

Let me know if this answers your question.

ifle commented 6 years ago

Thanks for your answer. You example put the instance name instead of role name. When I need to place your code? I have microservice architecture and want to share one instance of the application insights with all services and web applications. What I need to do that all services\applications is appear in the application map?

tomaszglinski commented 6 years ago

++ for ifle's question. I am going by https://github.com/AzureCAT-GSI/DevCamp/tree/master/HOL/java/06-appinsights. In startup logs I see INFO entries like "Registering WebApp with name 'myAPP'" which looks fine

But in Analytics the cloud_RoleName column is always empty, cloud_RoleInstance is my address (which is ok), appId is an UUID, appName is my app insights deployment name. I see no column with "myAPP"...

tomaszglinski commented 6 years ago

OK found it:

  public class CloudRoleNameInitializer extends WebTelemetryInitializerBase {

    @Override
    protected void onInitializeTelemetry(Telemetry telemetry) {
        telemetry.getContext().getTags().put(ContextTagKeys.getKeys().getDeviceRoleName(), "myapp");
    }
  }

and add entry to the Appinsights xml file a reference to the class under <TelemetryInitializers>

ifle commented 6 years ago

You can also use context.getDevice().setRoleName("myapp");

dhaval24 commented 6 years ago

@tomaszglinski and @ifle both the methods are correct code wise. However, personally @tomaszglinski method is more elegant from design and software engineering perspective as it keeps separation of concerns and you would less likely want to alter your business logic class for this purpose. since there is an increased interest in Springboot we are working on creating SpringBoot starter for application insights. Please take a look at spring-boot-starter branch for details.

Would you like to have this CloudRoleNameInitializer auto-configured with the starter? I would like to get your feedback and also understand a better reasoning on how you use the cloud role name in multi-tenant and composite apps scenario.

PS: Also let me know if you would be interested in trying Alpha version SpringBootStarter which we plan to get out soon once the core pieces of autoconfiguration are in.

tomaszglinski commented 6 years ago

Hi @dhaval24,

Yes, I could check the alpha version.

Whether CloudRoleNameInitializer should be autoconfigured - I think so, as it defines the logical name of the component (of course it should take the spring.application.name property value). The host should be rather a fallback.

My scenario is following: I have an environment that have many (micro)services, that are of course deployed with more than one instance. Most of them are deployed on docker swarm, so the host of the service is basically meaningless (as it is a random string). So I am using the cloud role name to define the logical name of the service. And would like to see on the map how services are calling each other, which is what I still cannot achieve...

SergeyKanzhelev commented 6 years ago

I posted on how application maps are working and which data to use to build maps: http://apmtips.com/blog/2017/10/18/two-types-of-correlation/ Note, there are experimental map that may work better for your scenario.

dhaval24 commented 6 years ago

@tomaszglinski and @ifle were you able to see the see the different components in the app-map by explicitly setting the cloudRoleName instance? If not what is the behavior you are seeing after setting the cloudRoleName.

Also @SergeyKanzhelev post explains correlation and app map propogation extensively. I recommend you taking a look at it.

@grlima can comment more on this but I believe that the correlation implementation in java, respects fetching the app-id from backend and therefore multi-ikey scenario should be fine but I might be mistaken here.

tomaszglinski commented 6 years ago

Hi @dhaval24 I see my role names only on the preview map, on classic there is only one box with the instrumentation key.

@SergeyKanzhelev thnaks for great article, AFAIU you create telemetry data there on your own. This is of course what I would like to get for free from the SDK if possible :)

rlewan commented 6 years ago

@dhaval24 I would be keen to try the alpha of Spring Boot support too -- the solution proposed by @tomaszglinski works, but it's essentially static configuration. In our system we have App Insights support implemented as a separate library which services import as a dependency, so it won't work for us.

tomaszglinski commented 6 years ago

@rlewan why wouldn't it work? Just replace the app name with "spring.application.name" property and put the class to you lib...

rlewan commented 6 years ago

Will a class added to Appinsights xml be instrumented by Spring?

tomaszglinski commented 6 years ago

No, but you could use a static field with app name, that would be initialized by spring one it startups. Then every call to onInitializeTelemetry would use that field (assuming onInitializeTelemetry is called every time the telemetry is build and sent, didn't check)

rlewan commented 6 years ago

Something like that may possibly work but it's hacky and discouraged by Spring too (injecting into static fields). Would be nice to have a proper support for Spring applications :)

tomaszglinski commented 6 years ago

true and true

dhaval24 commented 6 years ago

@rlewan appreciate your support in trying out the Alpha version of the starter. Thank you very much also on referencing your PR on how you are achieving it by extending the initializer. Based on your implementation I would like to understand what is the possible drawback of the same? My thought was to have a default CloudRoleName Initializer for SpringBoot Starter which will essentially configure autoconfigure that bean and add populate the tag with SpringbootApplicationName. However, the initializer logic would probably remain the same to use @Value annotation to get the SpringBootAppName. If it fails then we can have host as back up.

Please feel free to open up the discussion here to understand what are + and -.

dhaval24 commented 6 years ago

@tomaszglinski you mentioned that you see the role names only in the preview map but not in the classic App Map. So this means that the changes are only working in the preview_map but not in classic_map? Let me know in which case I can touch back with map team and understand if it's expected behavior.

dhaval24 commented 6 years ago

@tomaszglinski just confirmed with App_Map team and it is totally expected that this cloud_role names will be seen only in the preview app map.

grlima commented 6 years ago

We've added documentation on cloud_roleName for Java: https://docs.microsoft.com/en-us/azure/application-insights/application-insights-correlation#role-name

tomaszglinski commented 6 years ago

@grlima I would also add a line about required edit in the AppInsights.xml file...

dhaval24 commented 6 years ago

@ifle @tomaszglinski @rlewan we have just released Application Insights SpringBoot Starter 1.0.0-BETA. Please give it a try and provide us with feedback if you can. Here is the link for the readme to get started.

https://github.com/Microsoft/ApplicationInsights-Java/blob/master/azure-application-insights-spring-boot-starter/README.md

tomaszglinski commented 6 years ago

@dhaval24 just to check - will the starter set spring application name as role name by itself or it needs to be done explicitely? Found nothing about that in readme.

dhaval24 commented 6 years ago

@tomaszglinski yes- the starter will auto configure the cloud_roleName to be the spring application name. It dynamically picks the value from (spring.application.name) property. I will update the readme with this note.

tomaszglinski commented 6 years ago

Hi, is the jar available in some repository or do I need to build it myself?

dhaval24 commented 6 years ago

@tomaszglinski the jar is available on maven central and you can pull it down in your maven/gradle project as maven dependency. Here is the readme for more details: https://github.com/Microsoft/ApplicationInsights-Java/blob/master/azure-application-insights-spring-boot-starter/README.md

tomaszglinski commented 6 years ago

@dhaval24 no it is not, since you have a type in artifact name in your readme.md!

http://mvnrepository.com/artifact/com.microsoft.azure/application-insights-spring-boot-starter - bad http://mvnrepository.com/artifact/com.microsoft.azure/applicationinsights-spring-boot-starter - good

dhaval24 commented 6 years ago

@tomaszglinski thanks for pointing it out. Readme has been fixed now!