Skip to content

Commit 35c5ece

Browse files
committed
adding support for traces
1 parent 0a9816d commit 35c5ece

File tree

10 files changed

+204
-29
lines changed

10 files changed

+204
-29
lines changed

package.json

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
"Continuous Delivery",
2525
"DevOps"
2626
],
27-
"badges": [
28-
{
27+
"badges": [{
2928
"url": "https://img.shields.io/github/stars/digma-ai/digma?style=social",
3029
"description": "Star Digma on Github",
3130
"href": "bit.ly/36LyUcr"
@@ -72,22 +71,18 @@
7271
"main": "./out/extension.js",
7372
"contributes": {
7473
"views": {
75-
"digma": [
76-
{
77-
"type": "webview",
78-
"id": "codeAnalytics",
79-
"name": "CodeAnalytics"
80-
}
81-
]
74+
"digma": [{
75+
"type": "webview",
76+
"id": "codeAnalytics",
77+
"name": "CodeAnalytics"
78+
}]
8279
},
8380
"viewsContainers": {
84-
"activitybar": [
85-
{
86-
"id": "digma",
87-
"title": "Digma",
88-
"icon": "icon.png"
89-
}
90-
]
81+
"activitybar": [{
82+
"id": "digma",
83+
"title": "Digma",
84+
"icon": "icon.png"
85+
}]
9186
},
9287
"configuration": {
9388
"properties": {
@@ -102,6 +97,9 @@
10297
"digma.environment": {
10398
"type": "string"
10499
},
100+
"digma.jaegerAddress": {
101+
"type": "string"
102+
},
105103
"digma.hideFramesOutsideWorkspace": {
106104
"type": "bool",
107105
"defult": true
@@ -162,4 +160,4 @@
162160
"node-sass": "^7.0.1",
163161
"typescript": "^4.4.4"
164162
}
165-
}
163+
}

src/decorators/hotspotMarkerDecorator.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,15 @@ export class HotspotMarkerDecorator implements vscode.Disposable
6262
const rangesByLevel: Dictionary<number, vscode.Range[]> = {};
6363
for(let methodInfo of docInfo.methods)
6464
{
65+
if (!methodInfo.nameRange)
66+
continue;
67+
6568
const score = docInfo.summaries.get(MethodCodeObjectSummary, methodInfo.symbol.id)?.score ?? 0;
6669
if(score < 70)
6770
continue;
6871

6972
const level = Math.floor((score/101)*this.LEVELS); // [0-100] => [0-9]
70-
const decorationType = this._decorationTypes[level];
73+
//const decorationType = this._decorationTypes[level];
7174
var s =new vscode.Position(methodInfo.nameRange!.end.line+1,
7275
0);
7376
var e = new vscode.Position(methodInfo.range.end.line,

src/settings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ export class Settings
3939

4040
public static readonly environment = new SettingsKey('environment', '');
4141

42+
public static readonly jaegerAddress = new SettingsKey('jaegerAddress', '');
43+
44+
4245
public static readonly hideFramesOutsideWorkspace = new SettingsKey('hideFramesOutsideWorkspace', true);
4346

4447
public static readonly sourceControl = new SettingsKey('sourceControl', SourceControlType.None);

src/views-ui/codeAnalytics/contracts.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ export namespace UiMessage
3333
export class OpenHistogramPanel {
3434
constructor(public span?: string, public instrumentationLibrary?:string){}
3535
}
36+
37+
export class OpenTracePanel {
38+
constructor(public traceIds?: string[], public span?:string, public jaegerAddress?:string){}
39+
}
3640
export class OpenRawTrace {
3741
constructor(public content?: string) {}
3842
}
@@ -64,9 +68,8 @@ export namespace UiMessage
6468
constructor(public htmlContent?: string) {}
6569
}
6670

67-
export class HistogramPanel{
68-
constructor(public data?: decimal[]) {}
69-
71+
export class TracePanel {
72+
constructor(public url?: string) {}
7073
}
7174

7275
export class GlobalInsightsList {

src/views-ui/codeAnalytics/main.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ window.addEventListener("load", () =>
2828
const overlay = $("#view-overlay");
2929
const tabsContainer = $("#view-tabs");
3030
const insightsTab = $("#view-insights");
31+
const tacePanel = $("#view-trace-panel");
32+
3133
const globalInsightsTab = $("#view-global-insights");
3234
const errorsTab = $("#view-errors");
3335

@@ -66,6 +68,8 @@ window.addEventListener("load", () =>
6668
}
6769
});
6870

71+
72+
6973
consume(UiMessage.Set.GlobalInsightsList, (event) => {
7074
if (event.htmlContent !== undefined) {
7175
globalInsightsTab.find("#insightList").html(event.htmlContent);
@@ -132,7 +136,33 @@ window.addEventListener("load", () =>
132136

133137
publish(new UiMessage.Notify.OpenHistogramPanel(spanName,spanInstrumentationLibrary));
134138
});
135-
139+
140+
$(document).on("click", ".trace-link", function () {
141+
const traceIds = $(this).data("trace-id").split(",");
142+
const span = $(this).data("span-name");
143+
const jaeger = $(this).data("jaeger-address");
144+
145+
publish(new UiMessage.Notify.OpenTracePanel(traceIds,span, jaeger));
146+
});
147+
148+
consume(UiMessage.Set.TracePanel, (event) => {
149+
150+
151+
if (event.url !== undefined) {
152+
153+
fetch(event.url, { mode: 'cors'}).then(async response=>{
154+
switch (response.status) {
155+
// status "OK"
156+
case 200:
157+
tacePanel.find("#trace-jaeger-content").html(await response.text());
158+
// status "Not Found"
159+
case 404:
160+
throw response;
161+
}
162+
});
163+
164+
}
165+
});
136166

137167

138168
$(document).on("click", ".error_frames_btn", function () {

src/views/codeAnalytics/InsightListView/EndpointInsight.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,6 @@ export class SlowestSpansListViewItemsCreator implements IInsightListViewItemsCr
162162
this._editorHelper.openFileAndLine( doc,line );
163163
}
164164

165-
private duration(duration: Duration) {
166-
return `${duration.value} ${duration.unit}`;
167-
}
168-
169165
public async createListViewItem(codeObjectsInsight: SlowestSpansInsight): Promise<IListViewItem> {
170166

171167
var spans = codeObjectsInsight.spans;

src/views/codeAnalytics/InsightListView/ItemRender/SpanItemRendering.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import moment = require("moment");
2+
import { decimal } from "vscode-languageclient";
3+
import { Settings } from "../../../../settings";
24
import { WebViewUris } from "../../../webViewUtils";
35
import { Duration } from "../CommonInsightObjects";
46
import { SpanDurationsInsight } from "../SpanInsight";
@@ -53,9 +55,20 @@ export class SpanItemHtmlRendering{
5355
//todo move to file settings
5456
const tolerationConstant = 10000;
5557

58+
let traceIds: string[] = [];
59+
let traceLabels: string[] = [];
60+
5661
for(const item of insight.percentiles){
62+
63+
const percentileName= `P${item.percentile*100}`;
64+
65+
if (item.traceIds){
66+
traceIds.push(item.traceIds.firstOrDefault());
67+
traceLabels.push(percentileName);
68+
}
69+
5770
let changeMeaningfulEnough = false;
58-
percentileHtmls.push(/*html*/ `<span>P${item.percentile*100}</span>`);
71+
percentileHtmls.push(/*html*/ `<span>${percentileName}</span>`);
5972
percentileHtmls.push(/*html*/ `<span>${item.currentDuration.value} ${item.currentDuration.unit}</span>`);
6073
if (item.previousDuration &&
6174
item.changeTime ){
@@ -89,7 +102,23 @@ export class SpanItemHtmlRendering{
89102

90103
}
91104

105+
let traceHtml = ``;
106+
if (Settings.jaegerAddress.value){
107+
108+
92109

110+
const traceLabelsAtt = `data-trace-label="${traceLabels.join(",")}"`;
111+
const traceIdAtt = `data-trace-id="${traceIds.join(",")}"`;
112+
113+
114+
traceHtml=`
115+
<span style="padding-left: 10px;" class="trace-link link" data-jaeger-address="${Settings.jaegerAddress.value}" data-span-name="${insight.span}"
116+
${traceLabelsAtt} ${traceIdAtt} >
117+
Compare
118+
</span>
119+
`;
120+
121+
}
93122
const html = /*html*/ `
94123
<div class="list-item span-durations-insight">
95124
<div class="list-item-content-area">
@@ -103,7 +132,8 @@ export class SpanItemHtmlRendering{
103132
<img class="insight-main-image" style="align-self:center;" src="${this._viewUris.image("histogram.png")}" width="32" height="32">
104133
<div class="insight-main-value histogram-link link" data-span-name=${insight.span.name} data-span-instrumentationlib=${insight.span.instrumentationLibrary}>
105134
Histogram
106-
</div>
135+
</div>
136+
${traceHtml}
107137
</div>
108138
</div>`;
109139
return html;

src/views/codeAnalytics/InsightListView/SpanInsight.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { decimal } from "vscode-languageclient";
44
import { EndpointSchema, UsageStatusResults } from "../../../services/analyticsProvider";
55
import { DocumentInfoProvider } from "../../../services/documentInfoProvider";
66
import { EditorHelper } from "../../../services/EditorHelper";
7+
import { Settings } from "../../../settings";
78
import { UiMessage } from "../../../views-ui/codeAnalytics/contracts";
89
import { IListViewItem, IListViewItemBase, InsightListGroupItemsRenderer } from "../../ListView/IListViewItem";
910
import { WebviewChannel, WebViewUris } from "../../webViewUtils";
@@ -15,6 +16,7 @@ export interface SpanUsagesInsight extends CodeObjectInsight
1516
{
1617
span: string,
1718
flows:{
19+
sampleTraceIds:string[],
1820
percentage: Number,
1921
firstService:{
2022
service: string,
@@ -69,15 +71,25 @@ export class SpanUsagesListViewItemsCreator implements IInsightListViewItemsCrea
6971
<span class="codicon codicon-arrow-small-right"></span>
7072
<span class="ellipsis" title="${flow.lastServiceSpan}">${flow.lastServiceSpan}</span>`;
7173

74+
let traceHtml = ``;
75+
if (Settings.jaegerAddress.value){
76+
traceHtml=`
77+
<span style="padding-left: 10px;" class="trace-link link" data-jaeger-address="${Settings.jaegerAddress.value}" data-span-name="${insight.span}" data-trace-id="${flow.sampleTraceIds?.firstOrDefault()}" >
78+
Trace
79+
</span>
80+
`;
81+
82+
}
7283
return /*html*/`<div class="flow-row flex-row">
7384
<span class="flow-percent">${flow.percentage.toFixed(1)}%</span>
7485
<span class="flex-row flex-wrap ellipsis">
7586
${firstServiceHtml}
7687
${intermediateSpanHtml}
7788
${lastServiceHtml}
7889
${lastServiceSpanHtml}
90+
${traceHtml}
7991
</span>
80-
</div>`
92+
</div>`;
8193
});
8294

8395
const html = /*html*/ `
@@ -105,6 +117,7 @@ export interface SpanDurationsInsight extends CodeObjectInsight{
105117
previousDuration: Duration
106118
changeTime: moment.Moment,
107119
changeVerified: boolean,
120+
traceIds: string[]
108121
}[]
109122
}
110123

@@ -225,6 +238,10 @@ export class SpanEndpointBottlenecksListViewItemsCreator implements IInsightList
225238
}
226239

227240
private getDescription(span: SlowEndpointInfo){
241+
if (span.p95){
242+
return `Up to ~${(span.p95.fraction*100.0).toFixed(3)}% of the entire request time (${span.p95.maxDuration.value}${span.p95.maxDuration.unit}).`;
243+
244+
}
228245
return `Up to ~${(span.p50.fraction*100.0).toFixed(3)}% of the entire request time (${span.p50.maxDuration.value}${span.p50.maxDuration.unit}).`;
229246
}
230247

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
import { UiMessage } from "../../../views-ui/codeAnalytics/contracts";
3+
import { WebviewChannel } from "../../webViewUtils";
4+
import fetch from "node-fetch";
5+
import { htmlPrefilter } from "jquery";
6+
7+
export class TracePanel {
8+
9+
10+
11+
constructor(private _channel: WebviewChannel){
12+
13+
}
14+
15+
public async loadData(traceId: string, jaegerAddress:string){
16+
17+
18+
// this._channel?.publish(
19+
// new UiMessage.Set.TracePanel(`${jaegerAddress}/trace/${traceId}?uiEmbed=v0`)
20+
// );
21+
22+
}
23+
24+
public async getHtml(traceIds: string[], traceIdLabels :string[], span:string, jaegerAddress:string):Promise<string>{
25+
26+
27+
// const traceHtmlResponse = await fetch(`${jaegerAddress}/trace/${traceId}?uiEmbed=v0`);
28+
// let html = await traceHtmlResponse.text();
29+
30+
// var html =`
31+
// <body>
32+
// <h1>Trace: ${span}</h1>
33+
// <div id="view-trace-panel" style="width:100%; height:500px;" data-jaeger-url="${jaegerAddress}/trace/${traceId}?uiEmbed=v0">
34+
// <div id="trace-jaeger-content"></div>
35+
// </div>
36+
// </body>`;
37+
38+
let html ="";
39+
40+
if (traceIds.length===1){
41+
const traceId = traceIds[0];
42+
html =`
43+
<body>
44+
<h1>Trace: ${span}</h1>
45+
<iframe style="width:100%; height:500px;"src="${jaegerAddress}/trace/${traceId}?uiEmbed=v0" title="Trace" ></iframe>
46+
</body>`;
47+
48+
}
49+
else if (traceIds.length===2){
50+
51+
52+
const src = `${jaegerAddress}/trace/${traceIds[0]}...${traceIds[1]}?cohort=${traceIds[0]}&cohort=${traceIds[1]}&uiEmbed=v0`;
53+
html =`
54+
<body>
55+
<h1>Trace: ${span}</h1>
56+
<iframe style="width:100%; height:500px;"src="${src}" title="Trace" ></iframe>
57+
</body>`;
58+
}
59+
60+
61+
62+
return html;
63+
64+
}
65+
}
66+

0 commit comments

Comments
 (0)