What tags are available in RestTemplate-instrumented spans using Spring Cloud Sleuth - resttemplate

I'm including Spring Cloud Sleuth + Zipkin 2.2.7 in my Spring Boot application, and am using injected RestTemplates so that calls to them are instrumented and sent to zipkin.
My zipkin spans arising from RestTemplate calls contain tags for http.method and http.path, but no other HTTP info.
Is there any way to surface query parameters in tags? Sometimes there is interesting information in them that would be really useful to surface in a tag (e.g. GET /foo?includeSuperSensitiveData=true).

Let me try to explain what is going on under the hood:
TraceRestTemplateBeanPostProcessor modifies all the RestTemplate beans. As you can see there, it injects a LazyTracingClientHttpRequestInterceptor that is using a brave.spring.web.TracingClientHttpRequestInterceptor to instrument the http calls. So this is done by Brave, not Sleuth.
You might be able to extend TracingClientHttpRequestInterceptor, add the details you need to your implementation and create a bean (you might need to disable the config class that creates it if there is no #ConditionalOnMissingBean).

Related

Application Insights end-to-end multi component logging in Azure Functions

End-to-end logging between multiple components using Application Insights (AI) is based on a hierarchical Request-Id header. So each component is responsible to honer a possible incoming Request-Id. To get the full end-to-end hierarchical flow correct in Application Insights the Request-Id header needs to be used as the AI Operation.Id and Operation.ParentId (as described here).
But when making a request with a Request-Id header to a Azure Function using a HttpTrigger binding for example (Microsoft.NET.Sdk.Functions 1.0.24) with integrated Application Insights configured (as described here) a completely new Operation.Id is created and used - causing the whole flow in AI to be lost. Any ideas on how to get around this?
Setting up a separate custom TelemetryClient might be an option. But seems to require a lot of configuration to get the full ExceptionTrackingTelemetryModule and DependencyTrackingTelemetryModule right - especially when using Functions v2 and Core (ref to AI config). Anyone go that successfully working?
This is not yet supported by Functions but should start working sometime early next year.
If you want to hack it through, you can add a reference to ApplicationInsights SDK for AspNetCore (v 2.4.1) and configure RequestTrackingTelemetryModule.
static Function1()
{
requestModule = new RequestTrackingTelemetryModule();
requestModule.Initialize(TelemetryConfiguration.Active);
}
private static RequestTrackingTelemetryModule requestModule;
This is pretty sketchy, not fully tested and has drawbacks. E.g. request collected is no longer augmented with functions details (invocation id, etc). To overcome it you need to get the real TelemetryConfiguration from the Function dependency injection container and use it to initialize the module.
It should be possible, but is blocked by some issue.
But even with the code above, you should get requests that respect incoming headers and other telemetry correlated to the request.
Also, when out-of-the-box support for correlation for http request is rolled out, this may break. So this is a hacky temporary solution, use it only if you absolutely have to.

How do I get access to Castle DynamicProxy generation options within MOQ?

Does MOQ give access to Castle's DynamicProxy generation? Or are there configurable static methods or something in the Castle namespace that would allow me to tune MOQ's proxy gen behavior?
Some Background
I am Mocking a WCF Service endpoint (IWhatever). WCF automatically adds Async call back options for methods (e.g. IWhatever.DoWork() is also realized as IWhatever.DoWorkAsync()).
I'm looking to use the Mock<IWhatever> object while self-hosting this service mock'd; basically spoof this external web service to my system. However, when [self-hosted] WCF tries to create a DoWorkAsync() method; it already exists... which ultimately throws errors when opening the self-hosted/mock'd IWhatever endpoint. ((NOTE: I don't have access to original contract to use directly)).
Sooo.. looks like Castle DynamicProxy allows for one to define which methods should be generated (see: http://kozmic.net/2009/01/17/castle-dynamic-proxy-tutorial-part-iii-selecting-which-methods-to/). I was thinking I would use to not intercept calls on methods ending with "[...]Async". However I don't see where I would add this customization rule in the proxy generation within MOQ; hence my question.

Add request interceptors to specific calls

I'm currently trying to figure out which options does retrofit offer to add an interceptor only to specific calls.
Background & use cases
I'm currently using retrofit 1.9
The use case is pretty simple. Imagine a user who needs to login and get a session token. There is a call.
/**
* Call the backend and request a session token
*/
#POST("auht_endpoint")
Observable<Session> login(...);
All other calls will require a token from the above session in the form of a request header. In other words, all subsequent calls will have a header which provides the session token to the backend.
My question
Is there a simple way of adding this header only to specific calls through interceptors?
What I've tried so far
Obviously the easiest approach was to add the #Header annotation to the specific calls and providing the token as a parameter
I guess one can inspect the url in the request inside the interceptor. Not very flexible.
Create different rest adapters with different interceptors. I heard you should avoid creating several instances of the rest adapter for performance reasons.
Additional info
I'm not committed to interceptors, I would use other solutions
I've said I'm using retrofit 1.9, but I'd be also interested in a way to do it with retrofit 2.x
Please note this is not an answer, comment box was too small.
I've recently had this problem and I came up to the same possible solutions as you.
First of all I put aside double adapters - thats a last resort.
#Header field seems ok, bacause you explicitly define that this specific request needs authorization. However it's kinda boring to use.
Url inspection in interceptor looks "ugly", but I've decided to go with that. I mean if all requests from a one specific endpoint need that authorization header then what's the problem?
I had two other ideas:
Somehow dynamically replace/modify okHttpClient which is used with Retrofit. After some tests I figured that it's not possible.
Maybe create some custom annotation #AddAuthorizationHeader to the call definition, which will do everything for you, but I guess it wouldn't be possible either.
And in this matter Retrofit 2.x doesn't bring anything new.

Do AOP violate layered architecture for enterprise apps?

The question(as stated in the title) comes to me as recently i was looking at Spring MVC 3.1 with annotation support and also considering DDD for an upcoming project. In the new Spring any POJO with its business methods can be annotated to act as controller, all the concerns that i would have addressed within a Controller class can be expressed exclusively through the annotations.
So, technically i can take any class and wire it to act as controller , the java code is free from any controller specific code, hence the java code could deal with things like checking security , starting txn etc. So will such a class belong to Presentation or Application layer ??
Taking that argument even further , we can pull out things like security, txn mgmt and express them through annotations , thus the java code is now that of the domain object. Will that mean we have fused together the 2 layers? Please clarify
You can't take any POJO and make it a controller. The controller's job is get inputs from the browser, call services, prepare the model for the view, and return the view to dispatch to. It's still a controller. Instead of configuring it through XML and method overrides, you configure it through annotations, that's all.
The code is very far from being free from any controller specific code. It still uses ModelAndView, BindingResult, etc.
I'll approach the question's title, regarding AOP:
AOP does not violate "layered architecture", specifically because by definition it is adding application-wide functionality regardless of the layer the functionality is being used in. The canonical AOP example is logging: not a layer, but a functionality--all layers do logging.
To sort-of tie in AOP to your question, consider transaction management, which may be handled via Spring's AOP mechanism. "Transactions" themselves are not specific to any layer, although any given app may only require transactions in only a single layer. In that case, AOP doesn't violate layered architecture because it's only being applied to a single layer.
In an application where transactions may cross layers IMO it still doesn't violate any layering principles, because where the transactions live isn't really relevant: all that matters is that "this chunk of functionality must be transactional". Even if that transaction spans several app boundaries.
In fact, I'd say that using AOP in such a case specifically preserves layers, because the TX code isn't mechanically reproduced across all those layers, and no single layer needs to wonder (a) if it's being called in a transactional context, or (b) which transactional context it's in.

How to access 'templating' service not in controller

Ok, so the problem is:
I've got some 'order' entity, and it has 'status' property. On changing status, i wanted some other objects to be informed of this event, so i've decided to use Observer pattern. One of the observers notifies clients via email. Now i want to render Email text's from some of the twig templates. As i get from the Book, rendering templates in controllers are done with 'templating' service.
So the question as it follows: How can i access 'templating' service in my Observer class?
Specification:
I was advised, to implement my Observer as a service, but i'm not sure 'bout that. I've tried to solve this problem, and here is my options:
Use Registry. Solution that is straight and hard as rail. I guess it misses the whole point of DI and Service Container. Huge plus of this solution, is that i can access all common services from any point of my application.
To pass needed services from the context via constructor, or via setters. This is more like in Sf2 spirit. There comes another list of problems, which are not related to this question field.
Use observers as a service. I'm not really sure 'bout this option 'cos, in the book it is written, that service is a common functionality, and i don't think that observing entity with number of discrete properties is a common task.
I'm looking for a Sf2 spirit solution, which will be spread over whole project, so all answers with an explanation are appreciated.
As with any other service in a Symfony2 project, you can access it from within other classes through the dependency injector container. Basically what you would do is register your observer class as a service, and then inject the templating service into your observer service. See the docs for injecting services.
If you're not familiar with how Symfony handles dependency injection, I'd suggest reading that entire chapter of the documentation - it's very helpful. Also, if you want to find all the services that are registered for application, you can use the console command container:debug. You can also append a service name after that to see detailed info about the service.
Edit
I read your changes to the question, but still recommend going down the DI route. That is the Symfony2 spirit :) You're worried that your observer isn't common enough to be used as a service, but there's no hard rule saying "You must use this piece of code in X locations in order for it to be 'common'".
Using the DIC comes with another huge benefit - it handles other dependencies for you. Let's say the templating service has 3 services injected into itself. When using the DIC, you don't need to worry about the templating service's dependencies - they are handled for you. All you care about is telling it "inject the templating service into this other service" and Symfony takes care of all the heavy lifting.
If you're really opposed to defining your observer as a service, you can use constructor or setter injection as long as you're within a container-aware context.

Resources