clienttype

This commit is contained in:
Kinga Kazala 2023-08-10 14:00:02 +02:00
parent 24937ab171
commit 55f3113b10
8 changed files with 2707 additions and 2610 deletions

View File

@ -129,6 +129,19 @@ By default, caching duration is set to:
Cache duration for **Application Insights Dashboard** may be extended or disabled using web part properties panel. In case you want to delete the cache manually, the key names for this solution start with **spfxDashboard**. Cache duration for **Application Insights Dashboard** may be extended or disabled using web part properties panel. In case you want to delete the cache manually, the key names for this solution start with **spfxDashboard**.
### Rate Limit
This solution is using `clienttype` header to avoid using general tenant limits and to avoid the error 429 `Too many requests. Please retry.`
The **default rate limits** when querying cost management API **with/without** the `clienttype` parameter are:
| Response header |without `clienttype`| with `clienttype`|
|-|-|-|
|x-ms-ratelimit-remaining-microsoft.costmanagement-`clienttype-requests`|0|1995|
|x-ms-ratelimit-remaining-microsoft.costmanagement-`entity-requests`|2|0|
|x-ms-ratelimit-remaining-microsoft.costmanagement-`tenant-requests`|18|15|
The Cost Management API requests are still a subject to the rate limits. The above response headers, along with `x-ms-ratelimit-microsoft.costmanagement-qpu-consumed` (QPUs consumed by an API call) and `x-ms-ratelimit-microsoft.costmanagement-qpu-remaining` (list of remaining quotas) are printed in the browser console whenever a request to the API has been made
## Accessing Application Insights Data ## Accessing Application Insights Data

View File

@ -28,6 +28,7 @@
"chart.js": "2.9.4", "chart.js": "2.9.4",
"color": "4.2.3", "color": "4.2.3",
"moment": "^2.29.4", "moment": "^2.29.4",
"pnp-appinsights-listener": "^1.0.0",
"react": "17.0.1", "react": "17.0.1",
"react-dom": "17.0.1", "react-dom": "17.0.1",
"tslib": "2.3.1" "tslib": "2.3.1"

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ export class AppInsightsHelperSSO {
this.aadHttpClientFactory = config.aadHttpClientFactory; this.aadHttpClientFactory = config.aadHttpClientFactory;
this._postUrl = AppInsightsQueryHelper.GetAPIEndpoint(config.appId, config.endpoint); this._postUrl = AppInsightsQueryHelper.GetAPIEndpoint(config.appId, config.endpoint);
this.requestHeaders.append("Content-type", "application/json; charset=utf-8"); this.requestHeaders.append("Content-type", "application/json; charset=utf-8");
this.requestHeaders.append("clienttype", "pnp.apps.appinsights");
this.httpClientOptions = { headers: this.requestHeaders }; this.httpClientOptions = { headers: this.requestHeaders };
this.endpointType = config.endpoint; this.endpointType = config.endpoint;
this.cacheDuration = cache.cacheDuration; this.cacheDuration = cache.cacheDuration;
@ -105,6 +106,7 @@ export default class AppInsightsHelper {
this._postUrl = AppInsightsQueryHelper.GetAPIEndpoint(config.appId, config.endpoint); this._postUrl = AppInsightsQueryHelper.GetAPIEndpoint(config.appId, config.endpoint);
this.requestHeaders.append("Content-type", "application/json; charset=utf-8"); this.requestHeaders.append("Content-type", "application/json; charset=utf-8");
this.requestHeaders.append("x-api-key", config.appKey); this.requestHeaders.append("x-api-key", config.appKey);
this.requestHeaders.append("clienttype", "pnp.apps.appinsights");
this.httpClientOptions = { headers: this.requestHeaders }; this.httpClientOptions = { headers: this.requestHeaders };
this.endpointType = config.endpoint; this.endpointType = config.endpoint;
this.cacheDuration = cache.cacheDuration; this.cacheDuration = cache.cacheDuration;

View File

@ -83,9 +83,11 @@ export interface IDashboardConfig{
export interface IAppInsightsWebPartProps extends IAppInsightsConfig, IAppInsightsQuery, ICacheConfig, ILayoutConfig, IDashboardConfig { export interface IAppInsightsWebPartProps extends IAppInsightsConfig, IAppInsightsQuery, ICacheConfig, ILayoutConfig, IDashboardConfig {
isDevMode: boolean; isDevMode: boolean;
logLevel?: number; logLevel?: number;
appInsightsConnString?: string;
} }
export interface ICostManagementWebPartProps extends ICostManagementConfig, ICostManagementQuery, ICacheConfig, ILayoutConfig, IDashboardConfig { export interface ICostManagementWebPartProps extends ICostManagementConfig, ICostManagementQuery, ICacheConfig, ILayoutConfig, IDashboardConfig {
logLevel?: number; logLevel?: number;
appInsightsConnString?: string;
} }

View File

@ -26,6 +26,7 @@ export default class CostMngmtHelper {
} }
); );
this.requestHeaders.append("Content-type", "application/json; charset=utf-8"); this.requestHeaders.append("Content-type", "application/json; charset=utf-8");
this.requestHeaders.append("clienttype", "pnp.apps.costmanagement");
this.httpClientOptions = { headers: this.requestHeaders }; this.httpClientOptions = { headers: this.requestHeaders };
this.cacheDuration = cache.cacheDuration; this.cacheDuration = cache.cacheDuration;
this.cacheKey = `${config.subscriptionId ?? ''}-${config.resourceGroupName ?? ''}-${config.managementGroupId ?? ''}-${cache.userLoginName}` this.cacheKey = `${config.subscriptionId ?? ''}-${config.resourceGroupName ?? ''}-${config.managementGroupId ?? ''}-${cache.userLoginName}`

View File

@ -5,9 +5,9 @@ import {
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import * as ReactDom from 'react-dom'; import * as ReactDom from 'react-dom';
import { ConsoleListener, Logger } from '@pnp/logging';
import PnPTelemetry from "@pnp/telemetry-js"; import PnPTelemetry from "@pnp/telemetry-js";
import strings from 'AppInsightsDasboardWebPartStrings'; import strings from 'AppInsightsDasboardWebPartStrings';
import { AppInsights, setLogger } from 'pnp-appinsights-listener';
import * as React from 'react'; import * as React from 'react';
import { ThemedPalette } from '../../common/ColorsHelper'; import { ThemedPalette } from '../../common/ColorsHelper';
import { CacheExpiration, IAppInsightsQuery, IAppInsightsWebPartProps } from '../../common/CommonProps'; import { CacheExpiration, IAppInsightsQuery, IAppInsightsWebPartProps } from '../../common/CommonProps';
@ -17,26 +17,24 @@ import { IApplicationInsightsLogsProps } from './components/IApplicationInsights
const telemetry = PnPTelemetry.getInstance(); const telemetry = PnPTelemetry.getInstance();
telemetry.optOut(); telemetry.optOut();
const LOG_SOURCE: string = 'Application Insights Logs WebPart';
export default class ApplicationInsightsLogsWebPart extends BaseClientSideWebPart<IAppInsightsWebPartProps> { export default class ApplicationInsightsLogsWebPart extends BaseClientSideWebPart<IAppInsightsWebPartProps> {
public onInit(): Promise<void> { public onInit(): Promise<void> {
const _setLogger = (): void => { if (this.properties.appInsightsConnString) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any const ai = AppInsights(this.properties.appInsightsConnString);
Logger.subscribe(new (ConsoleListener as any)()); setLogger({
appInsights: ai,
//default is 2 - Warning logLevel: this.properties.logLevel,
if (this.properties.logLevel && this.properties.logLevel in [0, 1, 2, 3, 99]) { console: true
Logger.activeLogLevel = this.properties.logLevel; });
} }
else {
Logger.write(`${LOG_SOURCE} ${this.manifest.version} activated`); setLogger({
Logger.write(`${LOG_SOURCE} Initialized with properties:`); logLevel: this.properties.logLevel,
Logger.write(`${LOG_SOURCE} ${JSON.stringify(this.properties, undefined, 2)}`); console: true
});
} }
_setLogger();
return Promise.resolve(); return Promise.resolve();
} }

View File

@ -1,9 +1,9 @@
import { Version } from '@microsoft/sp-core-library'; import { Version } from '@microsoft/sp-core-library';
import { IPropertyPaneConfiguration, PropertyPaneLabel } from '@microsoft/sp-property-pane'; import { IPropertyPaneConfiguration, PropertyPaneLabel } from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { ConsoleListener, Logger } from '@pnp/logging';
import PnPTelemetry from "@pnp/telemetry-js"; import PnPTelemetry from "@pnp/telemetry-js";
import stringsCommon from 'CommonDasboardWebPartStrings'; import stringsCommon from 'CommonDasboardWebPartStrings';
import { AppInsights, setLogger } from 'pnp-appinsights-listener';
import React from 'react'; import React from 'react';
import * as ReactDom from 'react-dom'; import * as ReactDom from 'react-dom';
import { ThemedPalette } from '../../common/ColorsHelper'; import { ThemedPalette } from '../../common/ColorsHelper';
@ -15,26 +15,23 @@ import { ICostInsightsDashboardProps } from './components/ICostInsightsDashboard
const telemetry = PnPTelemetry.getInstance(); const telemetry = PnPTelemetry.getInstance();
telemetry.optOut(); telemetry.optOut();
const LOG_SOURCE: string = 'Cost Insights WebPart';
export default class CostInsightsWebPart extends BaseClientSideWebPart<ICostManagementWebPartProps> { export default class CostInsightsWebPart extends BaseClientSideWebPart<ICostManagementWebPartProps> {
public onInit(): Promise<void> { public onInit(): Promise<void> {
const _setLogger = (): void => { if (this.properties.appInsightsConnString) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any const ai = AppInsights(this.properties.appInsightsConnString);
Logger.subscribe(new (ConsoleListener as any)()); setLogger({
appInsights: ai,
//default is 2 - Warning logLevel: this.properties.logLevel,
if (this.properties.logLevel && this.properties.logLevel in [0, 1, 2, 3, 99]) { console: true
Logger.activeLogLevel = this.properties.logLevel; });
} }
else {
Logger.write(`${LOG_SOURCE} ${this.manifest.version} activated`); setLogger({
Logger.write(`${LOG_SOURCE} Initialized with properties:`); logLevel: this.properties.logLevel,
Logger.write(`${LOG_SOURCE} ${JSON.stringify(this.properties, undefined, 2)}`); console: true
});
} }
_setLogger();
return Promise.resolve(); return Promise.resolve();
} }