I want to add a custom property to all traces in Application Insights.
In Asp.Net Core I've added this code
internal class TelemetryProperties : ITelemetryInitializer
{
private IConfiguration configuration;
public TelemetryProperties(IConfiguration configuration)
{
this.configuration = configuration;
}
// TODO: Not being added to all traces.
// http://apmtips.com/blog/2014/12/01/telemetry-initializers/
public void Initialize(ITelemetry telemetry)
{
var applicationName = configuration["Application:Name"];
telemetry.Context.Properties.Add("Application", applicationName);
}
}
and in the configure method of Startup.cs I have added:
TelemetryConfiguration.Active.TelemetryInitializers.Add(new TelemetryProperties(Configuration));
The intent was to add "Application" to all traces, even ones made automatically by Application Insights, but the effect is that it is ONLY being added to my custom traces that Im calling through my code.
How do I add a property to ALL traces, even ones I do not create.
Edit: The purpose of this is that I want to have multiple APIs in the same application insights log, but I want to be able to partition when neccessary by adding a defining property such as application name.
Modifying TelemetryConfiguration.Active is not the recommended approach in Asp.Net Core apps. Can you add the telemetry initializer using the below code in ConfigureServices ?
services.AddSingleton<ITelemetryInitializer, TelemetryProperties>();
https://github.com/Microsoft/ApplicationInsights-aspnetcore/wiki/Custom-Configuration#adding-new-telemetryinitializer
Please let me know if this helps.
I used your code(without change), and at my side, all the traces(the application insights adds, I didn't use any Trackxx methods) including the exception all have the property "Application". Please see the screenshots below:
If it still occurs in your side, please provide the screenshots of the appInsights' logs.
Related
Here's my scenario.
Application:
Created an asp.net core app
Grab an ILogger<T> logger;
logger.LogInformation(new EventId(123456, "HelloEvent"), "Hello there");
Infrastructure:
Deploy service fabric (via ARM template)
Deploy app to service fabric
Me:
Click around hopelessly looking for "Hello there" in my HelloEvent
So...
The BIG question: What are all the pieces of log collection/processing offered by Microsoft Azure, and how do they fit together?
Application Insights... Looks cool. I added .UseApplicationInsights() in my builder and .AddApplicationInsightsTelemetry(..) into my Startup.
And I get beautiful logs... ...about service fabric events, dependencies like http calls, etc. But I can't find my "Hello there" HelloEvent.
Where do I get it?
...
Moving onwards, I looked into logs, monitoring, etc, with Azure.
I find "Log Analytics", which looks cool. Apparently Application Insights uses it. But I already have Application Insights. Does that mean I have Log Analytics? Or do I create my own Log Analytics workspace. If so, do my logs go to two places? Do I connect Application Insights to it somehow?
The ARM template for that actually is from 2015 for something called OperationalInsights. Although there's a 2017 version in examples, but not in the reference documentation.
So Operational Insights? Apparently that's from some Microsoft Operations Management Suite / OMS. Which was MMS before...?
And the more recent docs all talk about "Azure Monitor". But that's not even something I can deploy in Azure. Is it just a concept?
…
All I want to do is collect logs somewhere and then have cool stuff to search & visualize them :)
...and I still haven't found my "HelloEvent"
Can anyone shed light on either my simple "Where's my HelloEvent" or speak to the bigger picture question "What are the pieces and how do they all fit together"?
Regarding the "Where's my HelloEvent" with application insights:
Please make sure in Startup.cs -> Configure method, you specify the loglevel to information, like below:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// other code
//specify the LogLevel to Information, the default is warning
loggerFactory.AddApplicationInsights(app.ApplicationServices,LogLevel.Information);
}
(Update)and if you want to include event id in the logs, Simply setup ApplicationInsightsLoggerOptions instance in Startup.ConfigureServices method.
services
.AddOptions<ApplicationInsightsLoggerOptions>()
.Configure(o => o.IncludeEventId = true);
My test code as below:
public class HomeController : Controller
{
ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation(new EventId(123456, "HelloEvent"), "Hello there");
return View();
}
// other code
}
And in the azure portal, I can see "hello there":
I have an ASP.NET Core 2 application hosted on Azure, and I added a new Application Settings MyNewSetting for my App in the Azure Portal.
How do I access that setting from a controller?
My code bellow:
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSecrets>(Configuration);
services.AddSingleton<ITableRepositories, TableClientOperationsService>();
//...
My Controller:
public class RecordController : Controller
{
const int MyNewSetting = 7; // this one to replace with Azure Setting one
private readonly ITableRepositories repository;
public RecordController(ITableRepositories rep) {
repository = rep;
}
Here, I need probably to add FromServices injection, but I am not sure if it will work...
EDIT:
Folowing the #dee_zg answer, the following code could probably do the job:
public class RecordController : Controller
{
int MyNewSetting = 7;
private readonly ITableRepositories repository;
public RecordController(ITableRepositories rep) {
repository = rep;
int myInt;
if (int.TryParse(System.Environment.GetEnvironmentVariable("MY_NEW_SETTING"),
out myInt)) {
MyNewSetting = myInt;
};
}
You can choose to either get them from AppSettings["your-key"] collection or as environment variables: Environment.GetEnvironmentVariable("your-key").
From there you can map them to your custom IOptions and inject wherever you need them.
There's quite a few things you can do.
Use Options and configuration objects
The options pattern uses custom options classes to represent a group of related settings. We recommended that you create decoupled classes for each feature within your app.
Use an IOptionsSnapshot.
IOptionsSnapshot supports reloading configuration data when the configuration file has changed. It has minimal overhead. Using IOptionsSnapshot with reloadOnChange: true, the options are bound to Configuration and reloaded when changed.
... (see documentation)
In short, have a look at Configuration in ASP.NET Core, determine the scenario that best fits your needs and have at it!
Hope this helps.
I noticed that App Insights has a field called appName (and appId) when querying in the analytics tool (see below), however I don't see a way of setting this in the client library. Can this be set?
I'm trying to log related items to app insights, though the log source may be different. Using that field seems like a nice way to handle that scenario, though I'm open to different scenarios.
There is a preview where you can set the application name. This is done in the following way:
enable the preview Application Map
set the ITelemetry.Context.Cloud.RoleName (this is the application name)
Enable preview: Go to the portal -> the application insights -> previews -> Enable Multi-role Application Map
Set the application name:
This is done by adding an interceptor:
public class ServiceNameInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
telemetry.Context.Cloud.RoleName = "MyProcessName";
// RoleInstance property modifies the app name in the telmetry dashboard
telemetry.Context.Cloud.RoleInstance = "MyAppInstanceName";
}
}
Add the interceptor to the application insights configuration in startup.cs:
private void ConfigureAppInsights(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry(Configuration);
TelemetryConfiguration.Active.TelemetryInitializers
.Add(new ServiceNameInitializer());
}
Read more at: cross-process-application-insights-with-multi-role-application-map
Those values are populated in the backend and specify Application Insights resource details and thus cannot be changed.
What your're looking for is custom dimensions.
For example, to send the telemetry:
EventTelemetry telemetry = new EventTelemetry("my custom event");
telemetry.Properties.Add("MyApp", "HelloWorld");
telemetryClient.TrackEvent(telemetry);
To query those custom dimensions:
customEvents
| where customDimensions['MyApp'] == "HelloWorld"
I'm trying to follow this link to set up logging for my ASP.NET 5 app in azure https://docs.asp.net/en/latest/fundamentals/logging.html but can't make it work.
What is the way to do it?
You can configure logging through the Startup constructor. Here is a sample:
public Startup(ILoggerFactory loggerFactory)
{
var serilogLogger = new LoggerConfiguration()
.WriteTo
.TextWriter(Console.Out)
#if DNX451
.WriteTo.Elasticsearch()
#endif
.MinimumLevel.Verbose()
.CreateLogger();
loggerFactory.MinimumLevel = LogLevel.Debug;
loggerFactory.AddSerilog(serilogLogger);
}
That's all you need for configuration. From there, you can inject either ILoggerFactory or ILogger<T> (which is mostly the type for the class you want to inject the logger into) to the places you want to log stuff.
My sample configuration makes use of Serilog.Framework.Logging version 1.0.0-rc1-final-10071. Also, under dnx451, it will use Serilog.Sinks.ElasticSearch version 2.0.60.
In Azure Web App, there is no difference the way you configure it. You just need to choose the right provider.
You can see the entire sample here. Also check out ASP.NET 5 and Log Correlation by Request Id which might give you some more ideas.
At this point Azure AppService doesn't support ASP.NET 5 standard trace logging. Here is a potential workaround:
https://github.com/davidebbo-test/ConsoleInterceptor
I have a Azure Mobile Services project. When running locally everything works fine, the Application_Start() method gets called which in turn calls my WebApiConfig.Register() method.
However, when published to a live Azure Mobile Services server the Application_Start() does not get called along with the WebApiConfig.Register().
In the servers log I have the following entry:
No bootstrapper found -- using default bootstrapper. A bootstrapper can be specified in one of two ways: Either by defining a public, static class with name 'WebApiConfig' having a public parameter-less member called 'Register', or using the 'IBootstrapper' attribute to define a public class with a default constructor.
Why is Azure Mobile Services not picking up my BootStrapping WebApiConfig?
public static class WebApiConfig
{
public static void Register()
{
Trace.TraceInformation("Hello from WebApiConfig Register().");
// Use this class to set configuration options for your mobile service
ConfigOptions options = new ConfigOptions();
// Use this class to set WebAPI configuration options
HttpConfiguration config = ServiceConfig.Initialize(new ConfigBuilder(options));
// To display errors in the browser during development, uncomment the following
// line. Comment it out again when you deploy your service for production use.
// config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
}
}
public class WebApiApplication : System.Web.HttpApplication
{
public WebApiApplication()
{
Trace.TraceInformation("Hello from WebApiApplication ctor!");
}
protected void Application_Start()
{
Trace.TraceInformation("Hello from Application_Start()");
//RouteConfig.RegisterRoutes(RouteTable.Routes);
WebApiConfig.Register();
var dataContext = new DataContext();
dataContext.Database.Initialize(false);
}
}
Help is much appreciated!
That is bizarre... It really looks like you got it right. After working with .net backend azure mobile service for few weeks, I might suggest just maybe restart the service in portal and republish. I have hit some weird unexplained stuff just like you are and somehow fix like that.