Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/analyticsCodeLens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
if (!insight.decorators){
continue;
}
if (insight.environment=="PRODUCTIONS"){
continue;
}
for (const decorator of insight.decorators){

let envComponent = "";
Expand Down Expand Up @@ -128,7 +131,7 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
}) );
}
public async getLensForCodeLocationObject(methodInfo: MethodInfo, codeObjects: CodeObjectLocationInfo[],
usageStatus:UsageStatusResults, allInsights: CodeObjectInsight[] ) :Promise<vscode.CodeLens[]> {
usageStatus:UsageStatusResults, allInsights: CodeObjectInsight[], showNoData:boolean ) :Promise<vscode.CodeLens[]> {

let codelens: vscode.CodeLens[] = [];

Expand All @@ -139,10 +142,14 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
const insights = allInsights.filter(x=>x.codeObjectId== codeObject.id);
const codeObjectUsage = usageStatus.codeObjectStatuses.filter(x=>x.codeObjectId==codeObject.id);
if (insights.length==0 &&
codeObjectUsage.length==0){
codeObjectUsage.length==0 && showNoData){

const emptyLenses = await this.getNoDataCodeLens(methodInfo,codeObject);
for (const lens of emptyLenses){
if (codelens.any(x=>x.command?.title=="Never reached")){
continue;
}

codelens.push(lens);
}
}
Expand Down Expand Up @@ -202,6 +209,7 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
let spans = documentInfo.spans.filter(e => e.range.intersection(methodInfo.range) != undefined);
let duplicates = spans.filter(x=>documentInfo.spans.any(span=>span!=x && span.name==x.name && span.range!=x.range));
spans=spans.filter(span=>!duplicates.includes(span));
spans = spans.filter((v, i, a) => a.findIndex(x=>x.name==v.name) === i);

if(duplicates.length>0){
const lenses = await this.getDuplicateSpanLens(methodInfo, duplicates);
Expand All @@ -213,9 +221,13 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
}
if(spans.length>0){
const lenses = await this.getLensForCodeLocationObject(methodInfo,
spans,documentInfo.usageData.getAll(),documentInfo.insights.all.filter(x=>x.scope=="Span"));
spans,documentInfo.usageData.getAll(),documentInfo.insights.all.filter(x=>x.scope=="Span"), true);

for (const lens of lenses){
if (codelens.any(x=>x.command?.title==lens.command?.title
&& x.range.end==lens.range.end && x.range.start== lens.range.start)){
continue;
}
codelens.push(lens);
}

Expand All @@ -224,10 +236,13 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
const endpoints = documentInfo.endpoints.filter(e => e.range.intersection(methodInfo.range) != undefined);
if(endpoints.length>0){
const lenses = await this.getLensForCodeLocationObject(methodInfo,
endpoints,documentInfo.usageData.getAll(),documentInfo.insights.all.filter(x=>x.scope=="EntrySpan"|| x.scope=="Span"),
endpoints,documentInfo.usageData.getAll(),documentInfo.insights.all.filter(x=>x.scope=="EntrySpan"|| x.scope=="Span"),false
);

for (const lens of lenses){
if (codelens.find(x=>x.command?.title==lens.command?.title)){
continue;
}
codelens.push(lens);
}

Expand Down
18 changes: 9 additions & 9 deletions src/services/documentInfoProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ export class CodeObjectInsightsAccessor{

}

public byMethod(env: string, doc:DocumentInfo):InsightCodeObjectLink[] | undefined
public forDocument(env: string, doc:DocumentInfo):InsightCodeObjectLink[] | undefined
{
let result: InsightCodeObjectLink[] = [];
let insights = this._codeObjectInsights;
Expand Down Expand Up @@ -619,14 +619,14 @@ export class MethodInfo implements CodeObjectLocationInfo
public aliases: string[],
public relatedCodeObjects: CodeObjectLocationInfo[],
public documentUri: vscode.Uri){}

get idWithType(): string {
return 'method:' + this.id;
}

get idsWithType(): string[] {
return this.ids.map(x=> 'method:' + x);
}
public codeObjectType:string= "method";
get idWithType(): string {
return `${this.codeObjectType}:${this.id}`;
}
get idsWithType(): string[] {
return this.aliases.map(x=> `${this.codeObjectType}:${x}`);
}

get ids(): string[] {
return [
Expand Down
39 changes: 21 additions & 18 deletions src/services/languages/extractors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface SymbolInfo {
documentUri: vscode.Uri;
}


export interface CodeObjectLocationInfo extends CodeObjectInfo {
range: vscode.Range;
documentUri: vscode.Uri;
Expand All @@ -25,39 +26,41 @@ export class EndpointInfo implements CodeObjectLocationInfo {
public method: string,
public path: string,
public range: vscode.Range,
public documentUri: vscode.Uri,
) { }
public documentUri: vscode.Uri){}

get displayName(): string {
return this.method;
public codeObjectType: string = "endpoint";

get idsWithType() {
return [`${this.codeObjectType}:${this.id}`];
}
get displayName(): string {
return this.method;
}
get ids() {
return [ this.id];
}
}

get idsWithType() {
return ['endpoint:' + this.id];
}

get ids() {
return [ this.id];
}
}

export class SpanLocationInfo implements CodeObjectLocationInfo {
constructor(
public id: string,
public name: string,
public aliases: string[],
public duplicates: SpanLocationInfo[],
public range: vscode.Range,
public documentUri: vscode.Uri,
) { }
public documentUri: vscode.Uri)
{ }

public codeObjectType: string="span";

get idsWithType() {
return this.ids.map(x=> `${this.codeObjectType}:${x}`);
}

get displayName(): string {
return this.name;
}

get idsWithType() {
return this.ids.map(x=> 'span:' + x);
}

get ids() {
return [
Expand Down
4 changes: 3 additions & 1 deletion src/views/codeAnalytics/InsightListView/EndpointInsight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class UsageViewItemsTemplate {
private viewUris: WebViewUris
) { }

public generateHtml(
public generateHtml(
maxCallsIn1Min: number,
header: string,
description: string,
Expand Down Expand Up @@ -122,6 +122,8 @@ export interface HighUsageInsight extends EndpointInsight {
maxCallsIn1Min: number;
}



export interface SlowEndpointInsight extends EndpointInsight {
endpointsMedian: Duration;
endpointsMedianOfMedians: Duration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,24 @@ import { EndpointInsight, adjustHttpRouteIfNeeded, adjustHttpInsightIfNeeded } f
export interface CodeObjectInsight extends Insight{
codeObjectId: string,
environment: string,
category: string,
specificity: integer,

shortDisplayInfo: InsightShortDisplayInfo,
scope: string,
name: string,
importance: InsightImporance,
severity: decimal,
decorators: CodeObjectDecorator[]
}

export interface InsightShortDisplayInfo{
title:string,
targetDisplayName :string,
subtitle :string,
description :string
}

export enum InsightImporance {
spam = 9,
clutter = 8,
Expand Down
34 changes: 34 additions & 0 deletions src/views/codeAnalytics/StatusBar/insightFilterBar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as vscode from "vscode";
import { DigmaCommands } from "../../../commands";
import { WorkspaceState } from "../../../state";

export class InsightFilterStatusBar implements vscode.Disposable {

private _disposables: vscode.Disposable[] = [];
private _statusBar : vscode.StatusBarItem;

public constructor(private _state: WorkspaceState ){

this._statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10000);
this._disposables = [

this._statusBar
];

this._statusBar.text=`Usage Insights`;
this._statusBar.show();

}
dispose() {
for (let dis of this._disposables)
{
dis.dispose();
}
}

public refreshEnvironment(){

}


}
95 changes: 84 additions & 11 deletions src/views/codeAnalytics/StatusBar/insightsStatusBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import { DocumentInfo, DocumentInfoProvider } from "../../../services/documentIn
import { WorkspaceState } from "../../../state";
import { CodeObjectInsight, InsightImporance } from "../InsightListView/IInsightListViewItemsCreator";
import { QuickPickItem } from "vscode";
import { CodeObjectLocationInfo } from "../../../services/languages/extractors";
import { CodeObjectLocationInfo, SpanLocationInfo } from "../../../services/languages/extractors";
import { EditorHelper } from "../../../services/EditorHelper";
import { CodeObjectInfo } from "../codeAnalyticsView";
import { SlowestSpansInsight } from "../InsightListView/EndpointInsight";
import { Percentile } from "../InsightListView/CommonInsightObjects";

export interface InsightPickItem extends QuickPickItem{
location: CodeObjectLocationInfo;
Expand All @@ -20,6 +23,7 @@ export class InsightsStatusBar implements vscode.Disposable {




public constructor(private _state: WorkspaceState,
private _documentInfoProvider: DocumentInfoProvider,
private _editorHelper: EditorHelper,
Expand All @@ -33,22 +37,78 @@ export class InsightsStatusBar implements vscode.Disposable {

if (doc!=null){
const docInfo = await _documentInfoProvider.getDocumentInfo(doc)
const insightsByMethod = (docInfo)?.insights.byMethod(_state.environment,docInfo);
const documentInsights = (docInfo)?.insights.forDocument(_state.environment,docInfo);
const insightsByType = documentInsights?.groupBy(x=>x.insight.type);
const insightsSorted = documentInsights?.sort((a,b)=>a.insight.importance-b.insight.importance)
.map(x=>x.insight.type);

if (insightsByMethod!=null){

const distinctInsights = [...new Set(insightsSorted)];

let items : QuickPickItem[]= [];

if (insightsByType!=null && documentInsights!=null){
for (const insightType of distinctInsights){
let insightsForType = insightsByType[insightType];
const insight= insightsForType.firstOrDefault();

items.push({
label: `${this.getInsightEmoji(insight.insight)} ${insight.insight.name}`,
kind: vscode.QuickPickItemKind.Separator,

});

if (insight.insight.shortDisplayInfo){
const insightItems = insightsForType.map(x=>({
label: `${this.getCodeObjectTypeEmoji(x.insight)} ${x.insight.shortDisplayInfo.targetDisplayName}`,
description: `${x.insight.shortDisplayInfo.subtitle}`,
detail: `${x.insight.shortDisplayInfo.description}`,
location: x.codeObject
}));

items=items.concat(insightItems);


}

// if (insightType=="SlowestSpans"){
// const slowestSpans = insightsForType.map(x=> ( {
// insight: x.insight as SlowestSpansInsight,
// method: x.method,
// codeObject: x.codeObject
// }))


// .map(x=> ({
// label: `${this.getCodeObjectTypeEmoji(x.insight)} ${x.insight.endpointSpan}`,
// description: `${x.insight.spans.length} spans`,
// detail: `${this.getBottleneckString(x.insight.spans.flatMap(y=>[({y:y,p:y.p50}), ({y:y,p:y.p95}), ({y:y,p:y.p99})])
// .reduce((prev, current)=>(prev.p.fraction>current.p.fraction) ? prev : current))}`,
// location: x.codeObject
// }));
// items=items.concat(slowestSpans);

// }
else{
const typeInsightsItems = insightsForType.map(x=> ({
label: `${this.getCodeObjectTypeEmoji(x.insight)} ${x.insight.name}`,
description: x.codeObject.id.split("$_$")[1],
detail: `method: ${x.method.name}`,
location: x.codeObject
}));
items=items.concat(typeInsightsItems);

}



}
const quickPick = vscode.window.createQuickPick();
quickPick.items = insightsByMethod.map(x=> ({
label: `${this.getInsightEmoji(x.insight)} ${x.insight.name}`,
description: x.codeObject.id.split("$_$")[1],
detail: `method: ${x.method.name}`,
location: x.codeObject
}));
quickPick.items =items
await quickPick.onDidChangeSelection(async selection => {
if (selection[0]) {
const item = selection[0] as InsightPickItem;
const file = await _editorHelper.openTextDocumentFromUri(item.location.documentUri);
_editorHelper.openFileAndLine(file, item.location.range.start.line);
_editorHelper.openFileAndLine(file, item.location.range.start.line+1);
await vscode.commands.executeCommand("workbench.view.extension.digma");


Expand Down Expand Up @@ -103,6 +163,9 @@ export class InsightsStatusBar implements vscode.Disposable {
}
}

// private getBottleneckString(percentile: any):string{
// return `${percentile.p.fraction.toFixed(2)*100}% ${percentile.y.spanInfo.displayName} ${ percentile.p.maxDuration.value} ${ percentile.p.maxDuration.unit}`;
// }
private getInsightEmoji(insight:CodeObjectInsight) :string{
if (this.isInteresting(insight)){
return this.interestingEmoji;
Expand All @@ -113,6 +176,16 @@ export class InsightsStatusBar implements vscode.Disposable {

return '';
}

private getCodeObjectTypeEmoji(insight:CodeObjectInsight): string{
if (insight.scope=="Span"){
return '🔭';
}
if (insight.scope=="EntrySpan"){
return '⚆';
}
return '';
}
private isInteresting(insight:CodeObjectInsight) :boolean{

return insight.importance<=InsightImporance.interesting &&
Expand Down