Service Fabric and Application Insights - azure-service-fabric

I am new to service Fabric and trying to integrate my windows service application into service fabric. For logging information, we are planning to use Application Insights. But the events are not logged if i send it through my SF application. At the same time, through a normal console/windows application, I can able to log the message to applicationinsights and can be viewed from there.
Then I tried to create a VM in azure environment, and create SF application there and send the log information to AI and its worked successfully. I copied the same codebase into my local machine and run it, its not working. I am not sure whether its related to any firewall or proxy settings. Can anyone help on this?
I have used the nuget package to install Microsoft.ApplicationInsights dll in my machine. The version that I used is 2.2.0. And I am using .Net framework 4.6.1

You could look at EventFlow to help you capture Service Fabric ETW Events from your SF services and send them to Application Insights.
It's easy enough to setup, simply add Microsoft.Diagnostics.EventFlow.ServiceFabric NuGet to your Service Fabric service project and then setup a pipline
public static void Main(string[] args)
{
try
{
using (var diagnosticsPipeline = ServiceFabricDiagnosticPipelineFactory.CreatePipeline("MyApplication-MyService-DiagnosticsPipeline"))
{
ServiceRuntime.RegisterServiceAsync("MyServiceType", ctx => new MyService(ctx)).Wait();
ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(MyService).Name);
Thread.Sleep(Timeout.Infinite);
}
}
catch (Exception e)
{
ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
throw;
}
}
In your eventflow.config you can then setup Application Insights as an output:
{
"inputs": [
{
"type": "EventSource",
"sources": [
{ "providerName": "Your-Service-EventSource" }
]
},
],
"filters": [
{
"type": "drop",
"include": "Level == Verbose"
}
],
"outputs": [
// Please update the instrumentationKey.
{
"type": "ApplicationInsights",
"instrumentationKey": "00000000-0000-0000-0000-000000000000"
}
],
"schemaVersion": "2016-08-11",
"extensions": []
}

An alternative to the EventFlow approach suggested by yoape would be Azure Diagnostics (WAD).
Setup WAD in SF VMSS
When you're running an Azure Service Fabric cluster, it's a good idea
to collect the logs from all the nodes in a central location. Having
the logs in a central location helps you analyze and troubleshoot
issues in your cluster, or issues in the applications and services
running in that cluster. One way to upload and collect logs is to use
the Windows Azure Diagnostics (WAD) extension, which uploads logs to
Azure Storage, and also has the option to send logs to Azure
Application Insights or Event Hubs. You can also use an external
process to read the events from storage and place them in an analysis
platform product, such as OMS Log Analytics or another log-parsing
solution.
Setup AI upload in WAD
Cloud services, Virtual Machines, Virtual Machine Scale Sets and
Service Fabric all use the Azure Diagnostics extension to collect
data. Azure diagnostics sends data to Azure Storage tables. However,
you can also pipe all or a subset of the data to other locations using
Azure Diagnostics extension 1.5 or later. This article describes how
to send data from the Azure Diagnostics extension to Application
Insights.
The nice thing about it is that it's completely managed by Azure, and you don't need to change anything in your project.

You can adapt the watchdog Service from Microsoft Samples. The watchdog Service is a generic standalone Service Fabric Stateful Service that will log data into Application Insights.
Add the watchdog app and watchdog service into your solution.
Add your Azure App ID in the WatchDogService -PackageRoot/Config/ServiceManifest.xml
In the service that you need monitored, in the Run Async command, add the following lines (Example is in the Test Stateless Service provided in the link below)
Code:
protected override async Task RunAsync(CancellationToken cancellationToken)
{
// Register the health check and metrics with the watchdog.
bool healthRegistered = await this.RegisterHealthCheckAsync(cancellationToken);
bool metricsRegistered = await this.RegisterMetricsAsync(cancellationToken);
while (true)
{
// Report some fake metrics to Service Fabric.
this.ReportFakeMetrics(cancellationToken);
await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
// Check that registration was successful. Could also query the watchdog for additional safety.
if (false == healthRegistered)
{
healthRegistered = await this.RegisterHealthCheckAsync(cancellationToken);
}
if (false == metricsRegistered)
{
metricsRegistered = await this.RegisterMetricsAsync(cancellationToken);
}
}
}
Copy the RegisterHealthCheckAsync, RegisterMetricsAsync and ReportFakeMetrics methods, as is, into your service.cs file.
That should be it! It uses Azure Storage optionally. I did not have to implement that to get the watchdog up and running.
Here is the link : https://github.com/Azure-Samples/service-fabric-watchdog-service

For sending application/service telemetry to Application Insights, I strongly recommend you have a look at App Insights Service Fabric. It works great for:
Sending error and exception info
Populating the application map with all your services and their dependencies (including database)
Reporting on app performance metrics, as well as,
Tracing service call dependencies end-to-end,
Integrating with native as well as non-native SF applications
One thing however that the above won't solve is providing overall cluster health information - e.g. when/how often nodes go up/down, how much CPU/Memory and disk IO is consumed on individual nodes.
When running in Azure, the above should be fairly simple and I recommend you start here.
Doing this on-premise is not quite as simple. For this you could try MS EventFlow, or some of the other solutions already mentioned above.
Personally, I ended up creating a simple/custom windows service that use standard App Insights nuget packages to report the following info:
Cluster and Node ETW events from the Service Fabric Operational ETW channel
Performance counters (configurable via app insights config file)

Related

Log all exceptions in service fabric application

I have a bunch of backend service in Azure Service Fabric, I want to log any uncaught exceptions to App Insights, along with all my other logs. Is there any way in an Azure Service Farbic app to catch all uncaught exceptions and log them before re-throwing them?
You're using .net so you have access to the standard AppDomain way of handling all uncaught exceptions. Use this event.
Add the following lines into your Program.cs with logging code in there
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> {
//log exception
};
For sending application/service telemetry to Application Insights, I strongly recommend you have a look at App Insights Service Fabric. It works great for:
Sending error and exception info
Populating the application map with all your services and their dependencies (including database)
Reporting on app performance metrics, as well as,
Tracing service call dependencies end-to-end,
Integrating with native as well as non-native SF applications
If you're also interesting in monitoring the overall health of your cluster (e.g. CPU/Memory and when nodes go up/down), have a look at EventFlow or this github project

Hosting a Console application in Service Fabric

I'm starting with Service Fabric. I have created a very simple console application that runs the following code:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello world!");
File.AppendAllText("c:\\temp\\hello.txt", "Hello world!" + DateTime.Now.ToString() + "\r\n");
Console.ReadLine();
}
}
Then I create a guest executable project with Visual Studio and point it to the exe application. It gets installed in Service Fabric, I can see that the file is created, but then service fabric throws an error:
Error event: SourceId='System.FM', Property='State'.
Partition is below target replica or instance count.
fabric:/Test3/Test3Service -1 1 5ef5a0eb-5621-4821-95cb-4c1920ab7f0c
(Showing 0 out of 0 replicas. Total available replicas: 0.)
Is this approach correct? Can I have exe applications hosted in Service Fabric or do I need to implement/inherit from something?
EDIT
When the application is deployed it enters in a Warning state, showing the following messages:
Soon afterwards it transitions to an error state:
Yes you can host a simple Console Application in Service Fabric as a Guest Executable, that should not be a problem.
The issue you are seeing is likely because the application is trying to write to a file in c:/temp where your Guest Exe by default doesnt have permissions. Try removing that part of your sample code, or change it to write to hello.txt and it will end up in the same folder your Guest Exe is running in.
You should consider file storage on a Service Fabric node as temporary however and not rely on storing data there as your service could be moved between nodes by Service Fabric as part of it's cluster maintenance.
See this answer for some more details on file system access in SF https://stackoverflow.com/a/37966158/1062217

Not able to get the Metric charts displayed using Hystrix dashboard in Bluemix

I am trying to use Hystrix to implement service proxy to implement circuit breaker pattern. I did implement the Hystrix Commands and also package the Hystrix servlet to provide the Hystrix stream. To monitor the services, I am using the Hystrix Dashboard 1.5.0. All works fine on a local Tomcat server. I am able to see the metrics charts
However, when I deploy the same on Bluemix, the Dashboard does not show the charts. Instead it says 'Unable to connect to Command Metric Stream.'. I also checked the stream using Chrome browser. I am able to see the messages as below:
ping:
data:
{
"type":"HystrixCommand",
"name":"GetAllContactsCommand",
"group":"GetAllContactsService",
"currentTime":1464714539673,
"isCircuitBreakerOpen":false,
"errorPercentage":0,
"errorCount":0,
"requestCount":0,
"rollingCountBadRequests":0,
"rollingCountCollapsedRequests":0,
"rollingCountEmit":0,
"rollingCountExceptionsThrown":0,
"rollingCountFailure":0,
"rollingCountEmit":0,
"rollingCountFallbackFailure":0,
"rollingCountFallbackRejection":0,
"rollingCountFallbackSuccess":0,
"rollingCountResponsesFromCache":0,
"rollingCountSemaphoreRejected":0,
"rollingCountShortCircuited":0,
"rollingCountSuccess":0,
"rollingCountThreadPoolRejected":0,
"rollingCountTimeout":0,
"currentConcurrentExecutionCount":0,
"rollingMaxConcurrentExecutionCount":0,
"latencyExecute_mean":0,
"latencyExecute":{"0":0,
"25":0,
"50":0,
"75":0,
"90":0,
"95":0,
"99":0,
"99.5":0,
"100":0
},
"latencyTotal_mean":0,
"latencyTotal":
{ "0":0,
"25":0,
"50":0,
"75":0,
"90":0,
"95":0,
"99":0,
"99.5":0,
"100":0
},
"propertyValue_circuitBreakerRequestVolumeThreshold":20,
"propertyValue_circuitBreakerSleepWindowInMilliseconds":5000,
"propertyValue_circuitBreakerErrorThresholdPercentage":50,
"propertyValue_circuitBreakerForceOpen":false,
"propertyValue_circuitBreakerForceClosed":false,
"propertyValue_circuitBreakerEnabled":true,
"propertyValue_executionIsolationStrategy":"THREAD",
"propertyValue_executionIsolationThreadTimeoutInMilliseconds":1000,
"propertyValue_executionTimeoutInMilliseconds":1000,
"propertyValue_executionIsolationThreadInterruptOnTimeout":true,
"propertyValue_executionIsolationThreadPoolKeyOverride":null,
"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":10,
"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10,
"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,
"propertyValue_requestCacheEnabled":true,
"propertyValue_requestLogEnabled":true,
"reportingHosts":1
}
data:
{
"type":"HystrixThreadPool",
"name":"GetAllContactsService",
"currentTime":1464714539673,
"currentActiveCount":0,
"currentCompletedTaskCount":3,
"currentCorePoolSize":10,
"currentLargestPoolSize":3,
"currentMaximumPoolSize":10,
"currentPoolSize":3,
"currentQueueSize":0,
"currentTaskCount":3,
"rollingCountThreadsExecuted":0,
"rollingMaxActiveThreads":0,
"rollingCountCommandRejections":0,
"propertyValue_queueSizeRejectionThreshold":5,
"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,
"reportingHosts":1
}
Any idea, why the Dashboard is not able to connect to stream when deployed on Bluemix. Any help is appreciated.
Regards,
Umasuthan.
I have the same exact problem trying to run on Bluemix. I also run fine locally using Spring Tools Suite. Has there been a resolution to this problem?
My situation:
I used the Spring Initialzr to create a Spring Cloud application (Eureka, Hystrix, REST controller). I have deployed this to Bluemix (Cloud Foundry). Everything works fine except the Hystrix dashboard. I get "Unable to connect to Command Metric Stream." on the dashboard.
I can curl the stream url - it takes a really long time but data does come back.

Can I use multiple chaincode using a single Bluemix blockchain service?

I'm new to IBM Bluemix Blockchain service. I wonder if I can create multiple chain code. This is because I got the following error.
! looks like an error loading the chaincode or network, app will fail
{ name: 'register() error',
code: 401,
details: { Error: 'rpc error: code = 13 desc = \'server closed the stream without sending trailers\'' } }
Here is what I did:
Create a blockchain serivce, and nameded as 'blockchain'.
Run cp-web example => Success
Run marbles demo using existing blockchain service ('blockchain'). => Gives me the above error
Newly create a blockchain service, names as 'mbblochchain'
Repush marbles demo with new service name => Success
So I wonder if I can put multiple chaincode into peer's network or not. It is likely I may be misunderstanding how it works or should behave.
Yes you can deploy multiple chaincodes on the same network. The issue you are having is because each app is registering users differently.
Currently only 1 username (aka enrollID) can be registered against 1 peer. If you try to register the same username against two peers, the 2nd registration will fail. This is what is happening to you.
The Bluemix blockchain service is returning two type1 usernames (type1 is the type of enrollID these apps want to use).
cp-web will register the first and second enrollID against peer vp1
marbles will register the first enrollID against vp1 and the 2nd enrollID against vp2
Therefore when you ran marbles after cp-web it tried to register the 2nd enrollID against vp2 when it had already been registered with vp1. Thus giving you an error.
In general, you can deploy multiple chaincode apps to a single instance of the Bluemix Blockchain service and more broadly speaking multiple chaincode apps to a single peer network.
Were you deploying the web apps directly using "cf push" and trying to bind to existing Blockchain service instance or where you trying to use the "deploy to Bluemix" functionality?

Trouble adding a new service

I have followed the instructions at https://github.com/cloudfoundry/oss-docs/tree/master/vcap/adding_a_system_service and copied the echo service and created my new service. (That document is somewhat out-of-date in that "excluded components" no longer exists.
In any case, my service shows up as running with a gateway and a node when I look at 'vcap status' on the server. However, when I look at 'vmc services' from the client my service is not in the list. Where is this list maintained and why is my service not on the list?
Various services, including blob, filesystem, mongodb, etc, are shown on the 'vcm services' list even though they have never been included in my config. Where is this maintained and why are other services on this list?
The cloud_controller.log file shows a "Create service request:" for echo every minute. This service is not in my config file (it was once but it was removed and I repeated the deployment). What is prompting this request for a service that was not defined in the config?
The _gateway.log for my service shows the following:
INFO -- Sending info to cloud controller: ...api.vcap.me/services/v1/offerings
INFO -- Fetching handles from cloud controller .../offerings/.../handles
ERROR -- Failed registering with cloud controller, status=400
DEBUG -- [GaaS-Provisioner] Connected to node mbus..
ERROR -- Failed fetching handles, status=404
Why does my gateway fail to register with the cloud controller? I have found some reports that suggest that the problem is with domain name mapping. I have verified that the server can find itself:
$curl api.vcap.me
Welcome to VMware's Cloud Application Platform
What can I do to register my service?
You can also try asking your question on the vcap_dev google group.
https://groups.google.com/a/cloudfoundry.org/forum/?fromgroups#!forum/vcap-dev
They are focused in answering and discussing OSS subjects for Cloud Foundry!
If you follow the document correctly things should work just fine. I understand that the mechanism for maintaining the excluded list of components has changed and can be a point of confusion when following the steps mentioned in the article (just ignore that step totally).
ERROR -- Failed registering with cloud controller, status=400
Well this is a point of worry. I recently followed the article step by step and was able to add a new service.
Is the echo service showing up in vmc services?
Have you copied the the yml files for node and gateway at ./cloudfoundry/.deployments/devbox/config?
Are the tokens for your gateway unique? and matching in the two files? ./cloudfoundry/.deployments/devbox/config/cloud_controller.yml and ./cloudfoundry/.deployments/devbox/config/**_gateway.yml**
I would recommend that you first concentrate on getting the echo service to be listed in the vmc services output. Once done with this you should replicate the steps (with absolute care to modify things like the token) to get your custom service working.
Cheers,
Ankit
You should follow this guide
It work to me.
regards.