How to query Azure App Insights logs using Node.JS - node.js

There is an example how it is possible to query
LogAnalytics Workspace Logs or
Metrics for individual resources
using Node.Js:
But I could not find if there is an option to query Logs from AppInsights or from resource directly.
I need it to automate reporting of the performance, so I am planning to query requests table (we send logs using https://github.com/microsoft/ApplicationInsights-Java). Currently report is done manually using Performance blade of the AppInsights - checking Avg and 99 percentile for requests with specific filters on URL

You can setup logs ingestion from your application to Log Analytics Workspace using Diagnostic Settings. For example, if you host your app in WebApp you can send AppServiceHTTPLogs. And then in your Node.JS app you can use #azure/monitor-query package with a similar query:
let dataset=AppServiceHTTPLogs
| where CsHost == 'PUT_YOUR_HOSTNAME_HERE'
| where ScStatus == 200
| where CsUriStem contains 'FILTER_BY_URL_IF_YOU_NEED_IT';
dataset
| summarize arg_max(TimeTaken, CsUriStem)
| union(dataset
| summarize avg(TimeTaken), percentiles(TimeTaken, 99)
| extend CsUriStem='Overall')
That one is a close approximation of the performance blade from app insights.
And then your whole app could be
const azureLogAnalyticsWorkspaceId = "WORKSPACE_ID";
const logsQueryClient = new LogsQueryClient(new DefaultAzureCredential());
export async function runWebAppPerformance(startDate: Date, endDate: Date) {
const query = "PUT_YOUR_QUERY_HERE";
const result = await logsQueryClient.queryWorkspace(
azureLogAnalyticsWorkspaceId,
query,
{
startTime: startDate, endTime: endDate
}
);
if (result.status === LogsQueryResultStatus.Success) {
const tablesFromResult: LogsTable[] = result.tables;
if (tablesFromResult.length === 0) {
console.log(`No results for query`);
return;
}
processTables(tablesFromResult);
} else {
console.log(`Error processing the query - ${result.partialError}`);
}
}
async function processTables(tablesFromResult: LogsTable[]) {
const table = tablesFromResult[0];
const urlIndex = table.columnDescriptors.findIndex(c => c.name === "CsUriStem");
const timeTakenIndex = table.columnDescriptors.findIndex(c => c.name === "TimeTaken");
const avgIndex = table.columnDescriptors.findIndex(c => c.name === "avg_TimeTaken");
const ninetyNineindex = table.columnDescriptors.findIndex(c => c.name === "percentile_TimeTaken_99");
for (const row of table.rows) {
if (row[urlIndex] === "Overall"){
console.log(`${row[urlIndex]} (ms):`);
console.log(`Average: ${row[avgIndex]}; \t 99%: ${row[ninetyNineindex]}`);
}
else {
console.log(`MAX (ms)`);
console.log(`${row[urlIndex]}: \t ${row[timeTakenIndex]}`);
}
}
}

How to query Azure App Insights logs using Node.JS
In Azure Portal, Create Application Insights Instance and Copy the Instrumentation key from the overview page
Create a sample NodeJS Web App in Visual Studio code
We can add the instrumentation key in localhost or can be updated once after nodejs application is deployed to Azure.Here I have added the required application insight setting and deployed the App
In server.js, add
let appInsights = require('applicationinsights');
appInsights.setup("cc580d32-a7eb-41d7-b0e0-90ea0889fd10");
appInsights.start();
From the root folder of the Application, open the terminal and run
npm install applicationinsights --save
Deploy the Application to Azure
Browse the Application
View Logs in Application Insights
Application Insights queries are based on KQL
Navigate to Azure Portal => Your Application Insights Instance => Logs under Monitoring = > Click on traces
Metrics for individual resources using Node.Js
Navigate to metrics under Monitoring
Please refer Node.js services with Application Insights for more information

Related

What's missing for logging to App Insights in webjob?

I've a simple console app running both locally and as a webjob in App Service.
var configBuilder = new ConfigurationBuilder();
configBuilder.AddEnvironmentVariables();
configBuilder.AddUserSecrets<Program>();
var config = configBuilder.Build();
// Configure the LoggerFactory
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddConsole()
.SetMinimumLevel(LogLevel.Information)
.AddAzureWebAppDiagnostics();
// If the key exists in settings, use it to enable Application Insights.
string? connStr = config["APPLICATIONINSIGHTS_CONNECTION_STRING"];
Console.WriteLine(connStr);
if (!string.IsNullOrEmpty(connStr))
{
builder.AddApplicationInsightsWebJobs(o => o.ConnectionString = connStr);
Console.WriteLine("Application Insights enabled");
}
});
// Create a logger
var logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Test sending to App insights");
I want the last text in the last statement to be logged to App Insights. What's missing in my code?
I've run the code both locally and in Azure, neither alternative succeeds in sending the log to App Insights. I've also made sure that the connection string is correct.

Azure Ad integration in Azure functions with swagger

I am using Azure functions V3 with swagger UI. I am using the below code in my start up
builder.AddSwashBuckle(Assembly.GetExecutingAssembly(),opts => {
opts.SpecVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_0;
opts.Title = "Platform Data Operations";
});
I have configured the Azure Ad authentication for my app in the azure portal.
Set up the permissions and redirect Uri.I am able to login successfully from the browser after calling the redirect URI.
Can some one help me with how to integrate in the code.
You can follow the sample code below,
builder.AddSwashBuckle(Assembly.GetExecutingAssembly(), opts =>
{
opts.SpecVersion = OpenApiSpecVersion.OpenApi3_0;
opts.ConfigureSwaggerGen = (x =>
{
x.DocumentFilter<CustomSwaggerDocumentAttribute>();
x.EnableAnnotations();
x.CustomOperationIds(apiDesc =>
{
return apiDesc.TryGetMethodInfo(out MethodInfo methodInfo)
? methodInfo.Name
: new Guid().ToString();
});
});
// remove code as query parameter
opts.AddCodeParameter = false;
opts.PrependOperationWithRoutePrefix = true;
opts.Title = "Sample Function API Swagger";
});

Retrieve Google Cloud Pricing Information with Nodejs

I'm currently trying to retrieve Google cloud pricing information via Nodejs. The goal is to figure out what the current price of a compute engine instance is for a specific machine type.
Probably I have to use the billing catalog api but I am unable to make it work at all.
https://googleapis.dev/nodejs/billing/latest/google.cloud.billing.v1.CloudCatalog.html
I managed to retrieve the service id via the catalog api but that appears to be pretty pointless so far.
> const { CloudCatalogClient } = require('#google-cloud/billing')
> const client = new CloudCatalogClient()
> const list = await client.listServices()
>
> list.map(s => {
> s.map(a => {
> if(a.displayName === 'Compute Engine'){
> console.log(a)
> }
> })
>
> })
Outcome:
> {
> name: 'services/6F81-5844-456A',
> serviceId: '6F81-5844-456A',
> displayName: 'Compute Engine',
> businessEntityName: 'businessEntities/GCP'
> }
Could somebody help me out a bit? Thank you very much.
I believe you are looking for this
https://cloud.google.com/billing/v1/how-tos/catalog-api
Steps
Get services:
GET https://cloudbilling.googleapis.com/v1/services?key=API_KEY
Getting the list of SKUs for a service :
GET https://cloudbilling.googleapis.com/v1/services/SERVICE_ID/skus?key=API_KEY
See below test cases for the SDK you can probably use exiting SDK
Catalog API test cases

usage user details inside Azure App Insights

I have a .Net Core 3.1 API hosted in Azure App Service and this API uses the Azure AD to authenticate the users. I have requirement to show the list of users that have accessed this API.
app insights always show Zero users.
Things I have tried
Enabled the AppInsigts of web app
Enabled the telemetry in StartUp.cs
services.AddApplicationInsightsTelemetry(options => Configuration.Bind("ApplicationInsights", options))
Created the telemetry class to pass the User context
public void Initialize(ITelemetry telemetry)
{
var ctx = _httpContextAccessor.HttpContext;
if (ctx != null)
{
if (!string.IsNullOrEmpty(ctx.User.Identity.Name) &&
(string.IsNullOrEmpty(telemetry.Context.User.Id) || string.IsNullOrEmpty(telemetry.Context.Session.Id)))
{
telemetry.Context.User.Id = ctx.User.Identity.Name;
telemetry.Context.User.AuthenticatedUserId = ctx.User.Identity.Name;
telemetry.Context.Session.Id = ctx.User.Identity.Name;
}
}
}
Still I don't see any user in Azure portal

google-cloud/resource' cloud function not listing all projects in response

I am using a cloud function written in node.js to list projects this is the index.js file containing the method, When I trigger this function I am getting only 1 project printed. ProjectA -> the cloud function also resides in ProjectA, I have another ProjectB which is not getting printed which is also in ACTIVE mode. I have owner permission for both the projects.
const {Resource} = require('#google-cloud/resource');
const resource = new Resource();
async function getProjects() {
try {
// Lists all current projects
const [projects] = await resource.getProjects();
console.log(`success in getProjects() call`);
// Set a uniform endTime for all the resulting messages
const endTime = new Date();
const endTimeStr = endTime.toISOString();
// sample 2019-11-12T17:58:26.068483Z
for (var i=0; i<projects.length;i++) {
console.log("Total Projects ",projects.length) //Printing as 1 instead of correct 2
// Only publish messages for active projects
if (projects[i]["metadata"]["lifecycleState"] === config.ACTIVE) {
// Construct a Pub/Sub message
console.log(`About to send Pub/Sub message ${projects[i]}}`);
const pubsubMessage = {
"token": config.METRIC_EXPORT_PUBSUB_VERIFICATION_TOKEN,
"project_id": projects[i]["id"],
"end_time": endTimeStr
}
}
}
} catch(err) {
console.error("Error in getProjects()");
console.error(err);
throw err;
}
}
However if i try the google api link
https://cloud.google.com/resource-manager/reference/rest/v1/projects/list#try-it
I am getting 2 projects as response which i have access to.
When you execute a Cloud Function you choose a service account that will execute it, normally it's the "App Engine default service account (project-id#appspot.gserviceaccount.com), that service account should have the "Project Owner" role.
The API call from the API explorer uses an API key that it's tied to your user account no the service account used to execute the Cloud Functions, that's why it shows you all your projects.
To fix your issue just add the service account, that you're using to execute the Cloud Function, to all your Projects with the Project Owner role, although other roles (like Project Viewer) are enough to list it.

Resources