How to send spring boot actuator endpoint information to graphite? - graphite

I'm going to make application monitoring system. I'm using spring-boot actuator and I can make some information like metrics, health and etc. See a attatchment.
As you can see, there are so many things such as memory, heap to counter and gauges.(sample.actuator.SampleController.hello.* are made by com.codahale.metrics.annotation.Timed)
And I want to send those information to graphite to monitor. Google said those code.
#Configuration
public class MonitoringConfig {
#Autowired
private MetricRegistry metricRegistry;
#Bean
public GraphiteReporter graphiteReporter() {
Graphite graphite = new Graphite(new InetSocketAddress("70.50.8.111",
2003));
GraphiteReporter reporter = GraphiteReporter
.forRegistry(metricRegistry).prefixedWith("boot")
.build(graphite);
reporter.start(1000, TimeUnit.MILLISECONDS);
return reporter;
}
}
but reporter send only counter and gauge. For inserting other information to reporter, what should I do?
Please help....

Related

How to make logs in application insight without using Task.Delay method?

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp8
{
class Program
{
static IServiceCollection services = new ServiceCollection()
.AddLogging(loggingBuilder => loggingBuilder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("", LogLevel.Trace))
.AddApplicationInsightsTelemetryWorkerService("Application_Key");
static IServiceProvider serviceProvider = services.BuildServiceProvider();
static ILogger<Program> logger = serviceProvider.GetRequiredService<ILogger<Program>>();
static TelemetryClient telemetryClient = serviceProvider.GetRequiredService<TelemetryClient>();
static void Main(string[] args)
{
using (telemetryClient.StartOperation<RequestTelemetry>("AppointmentPatientCommunication"))
{
logger.LogInformation("1st");
hero();
logger.LogError("2nd");
telemetryClient.TrackTrace("Here is the error");
telemetryClient.Flush();
}
}
static void hero()
{
using (telemetryClient.StartOperation<RequestTelemetry>("AppointmentPatientCommunication"))
{
logger.LogInformation("2nd");
telemetryClient.Flush();
}
}
}
}
I uploading this console application as my webjob to make a log in application insight. I am trying to avoid the use of task.delay() so that I can get real-time logging at perfect timing. I am uploading this webjob triggered manually, but I see no entry in my application insights. Could anyone help me out with this one?
Telemetry is not sent instantly. Telemetry items are batched and sent by the ApplicationInsights SDK. In Console apps, which exits right after calling Track() methods, telemetry may not be sent unless Flush() and Sleep/Delay is done before the app exits as shown in full example later in this article. Sleep is not required if you are using InMemoryChannel. There is an active issue regarding the need for Sleep which is tracked here: link.
So there are two types of channels: InMemoryChannel and ServerTelemetryChannel
For more details about the both the channels click on this link.
In my program to deal with the issue, I used InMemoryChannel. In the below code, I have shown a portion of code to show how I added it in my program.
static IServiceCollection services = new ServiceCollection()
.AddLogging(loggingBuilder => loggingBuilder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("", LogLevel.Trace))
.AddSingleton(typeof(ITelemetryChannel), new InMemoryChannel())
.AddApplicationInsightsTelemetryWorkerService("Application_Key");
The Nuget Package I am using is Microsoft.ApplicationInsights.Channel
Thanks to # Peter Bons for your comment, Which helps to fix the problem.
The Flush() method in the Telemetry Client is used to flush the in-memory buffer when the application is shutting down. Normally, the SDK delivers data every 30 seconds or when the buffer is full (500 items), and there is no need to invoke the Flush() method manually for web applications unless the program is ready to be shut down.
The TelemetryClient object's Flush() method sends all of the data it presently holds in a buffer to the App Insights service.
Application Insights will transfer your data in batches in the background to make better use of the network.
In most cases, you won't need to call Flush(). However, if you know the process will leave after that point, you should execute Flush() to ensure that all of the data gets transmitted.
Here, I have added the Thread.Sleep(); call after the Flush Statement.
static void Main(string[] args)
{
using (telemetryClient.StartOperation<RequestTelemetry>("AppointmentPatientCommunication"))
{
logger.LogInformation("1st");
hero();
logger.LogError("2nd");
telemetryClient.TrackTrace("Here is the error");
# Flush takes some times to memory buffer at the shutdown activity.
telemetryClient.Flush();
# By default Flush takes 30 Sec so you have to wait for 30 sec.
Thread.Sleep(5000);
}
}
static void hero()
{
using (telemetryClient.StartOperation<RequestTelemetry>("AppointmentPatientCommunication"))
{
logger.LogInformation("2nd");
# Flush takes some times to memory buffer at the shutdown activity.
telemetryClient.Flush();
# By default Flush takes 30 Sec so you have to wait for 30 sec.
Thread.Sleep(5000);
}
}
Results in AI:

How to response with a success JSON format after completing a transaction in corda

Hi everyone i am working on a project in which i need to send a response in JSON format to the CLI that the Transaction have completed let me give you an example.Consider that i have stated a flow Start ExampleFlow pojo: {iouValue: 7}, otherParty: "O=PartyB,L=London,C=GB" and the result will be Starting
Generating transaction based on new IOU.
Verifying contract constraints.
Signing transaction with our private key.
Gathering the counter party's signature.
Collecting signatures from counterparties.
Verifying collected signatures.
Obtaining notary signature and recording transaction.
Broadcasting transaction to participants
Done
Flow completed with result: SignedTransaction(id=F95406D901209BA77396C1A4D375585C6E051414EE22BE441FC02E5AE147A050)
but what i want is that their should be a JSON format result not all of it but something like this
{response: success }
i just want some success response in JSON format
i am using IOU project
thanks
You can achieve that by establishing an RPC connection with your node; call the flow, then return the JSON object.
There are a couple of approaches that you can follow, and I recommend that you go through the samples repository https://github.com/corda/samples to explore them:
Create a webserver (SpringBoot application) that server REST API's that call your flows and return a JSON object: https://github.com/corda/samples/tree/release-V4/spring-webserver
Create a simple Java app that establishes an RPC connection with your node and serves as a client to call a certain method/flow: https://github.com/corda/samples/blob/release-V4/cordapp-example/clients/src/main/java/com/example/server/JavaClientRpc.java
If you follow the webserver sample, you can add a method to your controller that does something like:
#GetMapping(value = "/my-api", produces = MediaType.APPLICATION_JSON_VALUE)
private ResponseEntity<YourObject> getSomething() {
// Some code that calls your flow and returns YourObject.
return ResponseEntity.ok().body(YourObject);
}
so i got the answer what u need to do is add this dependency in client build.gradle
cordaCompile "net.corda:corda-jackson:$corda_release_version"
after that you just need to implement this code snip
String json = "";
try {
ObjectMapper mapper = JacksonSupport.createNonRpcMapper();
json = mapper.writeValueAsString(results);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return json;
result can be any datatype you want to convert to json

App Insights not using RequestTelemetryFilter for health check Controller in Spring Boot app

I have a Spring Boot app with a few Controllers I want to track their dependencies (including outbound Http requests). That all works as expected. However, I have one controller for a health check (returning 204) that I do not want telemetry for. All other responses mention custom code components, but according to the documentation, this should be doable within the AI-Agent.xml config.
<BuiltInProcessors>
<Processor type="RequestTelemetryFilter">
<Add name="NotNeededResponseCodes" value="204" />
</Processor>
</BuiltInProcessors>
I notice on the classpath that there are two RequestTelemtryFilter instances (one from ai-core and one from ai-web, neither of which get hit when i debug).
Configuring the Agent (via AI-Agent.xml) is different than configuring custom telemetry (via Applicationinsights.xml). Spring boot + the agent requires the use of a custom Telemetry Processor and pulling into your configuration via #Bean. No additional XML in the AI-Agent is necessary.
public class HealthCheckTelemetryFilter implements TelemetryProcessor
{
public HealthCheckTelemetryFilter()
{
// TODO Auto-generated constructor stub
}
#Override
public boolean process(Telemetry telemetry)
{
RequestTelemetry reqTel = (RequestTelemetry) telemetry;
if(reqTel.getResponseCode().equals(HttpStatus.NO_CONTENT.toString()))
return false;
else
return true;
}
}
NOTE: dont forget appropriate type check

How to add multiple Bindable services to a grpc server builder?

I have the gRPC server code as below:
public void buildServer() {
List<BindableService> theServiceList = new ArrayList<BindableService>();
theServiceList.add(new CreateModuleContentService());
theServiceList.add(new RemoveModuleContentService());
ServerBuilder<?> sb = ServerBuilder.forPort(m_port);
for (BindableService aService : theServiceList) {
sb.addService(aService);
}
m_server = sb.build();
}
and client code as below:
public class JavaMainClass {
public static void main(String[] args) {
CreateModuleService createModuleService = new CreateModuleService();
ESDStandardResponse esdReponse = createModuleService.createAtomicBlock("8601934885970354030", "atm1");
RemoveModuleService moduleService = new RemoveModuleService();
moduleService.removeAtomicBlock("8601934885970354030", esdReponse.getId());
}
}
While I am running the client I am getting an exception as below:
Exception in thread "main" io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method grpc.blocks.operations.ModuleContentServices/createAtomicBlock is unimplemented
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:233)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:214)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:139)
In the above server class, if I am commenting the line theServiceList.add(new RemoveModuleContentService()); then the CreateModuleContentService service is working fine, also without commenting all the services of RemoveModuleContentService class are working as expected, which means the problem is with the first service when another gets added.
Can someone please suggest how can I add two services to Server Builder.
A particular gRPC service can only be implemented once per server. Since the name of the gRPC service in the error message is ModuleContentServices, I'm assuming CreateModuleContentService and RemoveModuleContentService both extend ModuleContentServicesImplBase.
When you add the same service multiple times, the last one wins. The way the generated code works, every method of a service is registered even if you don't implement that particular method. Every service method defaults to a handler that simply returns "UNIMPLEMENTED: Method X is unimplemented". createAtomicBlock isn't implemented in RemoveModuleContentService, so it returns that error.
If you interact with the ServerServiceDefinition returned by bindService(), you can mix-and-match methods a bit more, but this is a more advanced API and is intended more for frameworks to use because it can become verbose to compose every application service individually.

WCF Client Proxies, Client/Channel Caching in ASP.Net - Code Review

long time ASP.Net interface developer being asked to learn WCF, looking for some education on more architecture related fronts - as its not my strong suit but I'm having to deal.
In our current ASMX world we adopted a model of creating ServiceManager static classes for our interaction with web services. We're starting to migrate to WCF, attempting to follow the same model. At first I was dealing with performance problems, but I've tweaked a bit and we're running smoothly now, but I'm questioning my tactics. Here's a simplified version (removed error handling, caching, object manipulation, etc.) of what we're doing:
public static class ContentManager
{
private static StoryManagerClient _clientProxy = null;
const string _contentServiceResourceCode = "StorySvc";
// FOR CACHING
const int _getStoriesTTL = 300;
private static Dictionary<string, GetStoriesCacheItem> _getStoriesCache = new Dictionary<string, GetStoriesCacheItem>();
private static ReaderWriterLockSlim _cacheLockStories = new ReaderWriterLockSlim();
public static Story[] GetStories(string categoryGuid)
{
// OMITTED - if category is cached and not expired, return from cache
// get endpoint address from FinderClient (ResourceManagement SVC)
UrlResource ur = FinderClient.GetUrlResource(_contentServiceResourceCode);
// Get proxy
StoryManagerClient svc = GetStoryServiceClient(ur.Url);
// create request params
GetStoriesRequest request = new GetStoriesRequest{}; // SIMPLIFIED
Manifest manifest = new Manifest{}; // SIMPLIFIED
// execute GetStories at WCF service
try
{
GetStoriesResponse response = svc.GetStories(manifest, request);
}
catch (Exception)
{
if (svc.State == CommunicationState.Faulted)
{
svc.Abort();
}
throw;
}
// OMITTED - do stuff with response, cache if needed
// return....
}
internal static StoryManagerClient GetStoryServiceClient(string endpointAddress)
{
if (_clientProxy == null)
_clientProxy = new StoryManagerClient(GetServiceBinding(_contentServiceResourceCode), new EndpointAddress(endpointAddress));
return _clientProxy;
}
public static Binding GetServiceBinding(string bindingSettingName)
{
// uses Finder service to load a binding object - our alternative to definition in web.config
}
public static void PreloadContentServiceClient()
{
// get finder location
UrlResource ur = FinderClient.GetUrlResource(_contentServiceResourceCode);
// preload proxy
GetStoryServiceClient(ur.Url);
}
}
We're running smoothly now with round-trip calls completing in the 100ms range. Creating the PreloadContentServiceClient() method and adding to our global.asax got that "first call" performance down to that same level. And you might want to know we're using the DataContractSerializer, and the "Add Service Reference" method.
I've done a lot of reading on static classes, singletons, shared data contract assemblies, how to use the ChannelFactory pattern and a whole bunch of other things that I could do to our usage model...admittedly, some of its gone over my head. And, like I said, we seem to be running smoothly. I know I'm not seeing the big picture, though. Can someone tell me what I've ended up here with regards to channel pooling, proxy failures, etc. and why I should head down the ChannelFactory path? My gut says to just do it, but my head can't comprehend why...
Thanks!
ChannelFactory is typically used when you aren't using Add Service Reference - you have the contract via a shared assembly not generated via a WSDL. Add Service Reference uses ClientBase which is essentially creating the WCF channel for you behind the scenes.
When you are dealing with REST-ful services, WebChannelFactory provides a service-client like interface based off the shared assembly contract. You can't use Add Service Reference if your service only supports a REST-ful endpoint binding.
The only difference to you is preference - do you need full access the channel for custom behaviors, bindings, etc. or does Add Service Reference + SOAP supply you with enough of an interface for your needs.

Resources