Skip to content

Commit

Permalink
Merge pull request #4093 from kubeshop/devcatalin/refactor/missing-te…
Browse files Browse the repository at this point in the history
…lemetry

improve telemetry
  • Loading branch information
devcatalin authored Jun 21, 2023
2 parents f729135 + 011ebc8 commit 34392c6
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 11 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/components/organisms/NewProject/NewProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const NewProject: React.FC = () => {
'Not sure where to start? Explore a sample project containing everything you need to get started with just one click.',
itemAction: () => {
dispatch(openGitCloneModal({fromSampleProject: true}));
trackEvent('app_start/create_project', {from: 'sample'});
},
},
{
Expand Down Expand Up @@ -105,6 +106,7 @@ const NewProject: React.FC = () => {
itemDescription: 'Create a new project from a Helm Chart in a Helm repository, and save it locally.',
itemAction: () => {
dispatch(openHelmRepoModal());
trackEvent('app_start/create_project', {from: 'helm'});
},
},
];
Expand Down
27 changes: 24 additions & 3 deletions src/editor/editor.instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ let isRecreatingModel = false;
let editorType: 'local' | 'cluster' | undefined;
let hasTypedInEditor = false;
let hasModelContentChanged = false;
let currentResourceKind: string | undefined;

export const didEditorContentChange = () => hasModelContentChanged;

Expand All @@ -36,7 +37,7 @@ export const mountEditor = (props: {element: HTMLElement; type: 'local' | 'clust
if (hasTypedInEditor) {
return;
}
trackEvent('edit/code_changes', {from: getEditorType()});
trackEvent('edit/code_changes', {from: getEditorType(), resourceKind: currentResourceKind});
hasTypedInEditor = true;
});
EDITOR.onDidChangeModelContent(e => {
Expand Down Expand Up @@ -81,6 +82,13 @@ export const setEditorNextSelection = (range: monaco.IRange) => {
};

export function recreateEditorModel(editor: monaco.editor.ICodeEditor, text: string, language: string = 'yaml') {
const kindMatch = text.match(/kind:\s*(\w+)/);
if (kindMatch?.length === 1) {
currentResourceKind = kindMatch[1];
} else {
currentResourceKind = undefined;
}

isRecreatingModel = true;
resetEditor();
editor.getModel()?.dispose();
Expand Down Expand Up @@ -113,10 +121,14 @@ export const clearEditorLinks = () => {
};

export const addEditorCommand = (payload: EditorCommand['payload'], supportHtml?: boolean) => {
const {text, altText, handler, beforeText, afterText} = payload;
const {text, altText, handler, beforeText, afterText, type} = payload;

const id = `cmd_${uuidv4()}`;
const disposable: monaco.IDisposable = monaco.editor.registerCommand(id, handler);
const wrappedHandler = () => {
trackEvent('editor/run_command', {type, resourceKind: currentResourceKind});
handler();
};
const disposable: monaco.IDisposable = monaco.editor.registerCommand(id, wrappedHandler);

let markdownLink: monaco.IMarkdownString;

Expand Down Expand Up @@ -170,11 +182,14 @@ monaco.languages.registerHoverProvider('yaml', {
provideHover: (model, position) => {
const positionHovers = editorHovers.filter(hover => isPositionInRange(position, hover.range));
if (positionHovers.length === 0) {
trackEvent('editor/hover', {resourceKind: currentResourceKind});
return null;
}
if (positionHovers.length === 1) {
trackEvent('editor/hover', {resourceKind: currentResourceKind, types: [positionHovers[0].type]});
return positionHovers[0];
}
trackEvent('editor/hover', {resourceKind: currentResourceKind, types: positionHovers.map(hover => hover.type)});
return {
contents: positionHovers.map(hover => hover.contents).flat(),
};
Expand All @@ -192,6 +207,12 @@ monaco.languages.registerLinkProvider('yaml', {
},
resolveLink: async link => {
const linksToResolve = editorLinks.filter(({range}) => isRangeInRange(range, link.range));
if (linksToResolve.length > 0) {
trackEvent('editor/follow_link', {
resourceKind: currentResourceKind,
types: linksToResolve.map(l => l.type),
});
}
const promises = linksToResolve.map(({handler}) => Promise.resolve(handler()));
await Promise.all(promises);
return {range: link.range};
Expand Down
3 changes: 3 additions & 0 deletions src/editor/editor.types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import * as monaco from 'monaco-editor';

export type EditorHover = {
type: string;
range: monaco.IRange;
contents: monaco.IMarkdownString[];
};

export type EditorLink = {
type: string;
range: monaco.IRange;
tooltip?: string;
handler: () => Promise<void> | void;
};

export type EditorCommand = {
payload: {
type: string;
text: string;
altText: string;
handler: monaco.editor.ICommandHandler;
Expand Down
4 changes: 4 additions & 0 deletions src/editor/enhancers/helm/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const helmTemplateFileEnhancer = createEditorEnhancer(({state, resourceId
typeof keyPathInFile.value === 'object' ? JSON.stringify(keyPathInFile.value, null, 4) : keyPathInFile.value;

const newCommand = addEditorCommand({
type: 'go_to_helm_values_file',
text: `${keyPathInFile.filePath}`,
altText: 'Select file',
handler: () => {
Expand Down Expand Up @@ -87,6 +88,7 @@ export const helmTemplateFileEnhancer = createEditorEnhancer(({state, resourceId
const text = hasMultipleLinks ? `Found this value in ${keyPathsInFile.length} helm value files` : ``;
if (!hasMultipleLinks) {
addEditorLink({
type: 'go_to_file',
range: helmFileValue.range,
tooltip: 'Open file',
handler: () => {
Expand All @@ -108,6 +110,7 @@ export const helmTemplateFileEnhancer = createEditorEnhancer(({state, resourceId

if (commands.length) {
addEditorHover({
type: 'helm_template_values_found',
range: helmFileValue.range,
contents: [createMarkdownString(text), ...commands.map(c => c.markdownLink)],
});
Expand All @@ -117,6 +120,7 @@ export const helmTemplateFileEnhancer = createEditorEnhancer(({state, resourceId
}

addEditorHover({
type: 'helm_template_values_not_found',
range: helmFileValue.range,
contents: [createMarkdownString('This value was not found in any helm values file.')],
});
Expand Down
2 changes: 2 additions & 0 deletions src/editor/enhancers/helm/valuesFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const helmValuesFileEnhancer = createEditorEnhancer(({state, resourceIden
decorations.push(createInlineDecoration(placeUsed.locationInValueFile, InlineDecorationTypes.SatisfiedRef));
placeUsed.uses.forEach(use => {
const newCommand = addEditorCommand({
type: 'go_to_helm_template_file',
text: `${use.filePath}`,
altText: 'Select file',
beforeText: 'Found in: ',
Expand All @@ -63,6 +64,7 @@ export const helmValuesFileEnhancer = createEditorEnhancer(({state, resourceIden

if (commands.length) {
addEditorHover({
type: 'helm_values_used_in_template',
range: placeUsed.locationInValueFile,
contents: commands.map(c => c.markdownLink),
});
Expand Down
7 changes: 6 additions & 1 deletion src/editor/enhancers/k8sResource/refs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,20 @@ ${outgoingRefsMarkdownTableRows.join('\n')}
);
}
addEditorHover({
type: 'list_outgoing_links',
range,
contents: hoverContents,
});

if (matchedRefs.length === 1 && getEditorType() !== 'cluster') {
const ref = matchedRefs[0];
addEditorLink({
type: 'go_to_outgoing_link',
range,
handler: () => onClickRefLink({resourceMeta, ref, dispatch}),
});
} else {
addEditorLink({range, handler: () => {}});
addEditorLink({type: 'go_to_outgoing_link', range, handler: () => {}});
}
});
});
Expand All @@ -196,6 +198,7 @@ const addEditorCommandForRef = (args: {resourceMeta: ResourceMeta; ref: Resource
if (ref.target.type === 'resource' && ref.target.resourceId) {
command = addEditorCommand(
{
type: 'go_to_resource',
text: 'Open resource',
altText: 'Open resource',
handler: () => {
Expand All @@ -215,6 +218,7 @@ const addEditorCommandForRef = (args: {resourceMeta: ResourceMeta; ref: Resource
} else if (ref.target.type === 'file') {
command = addEditorCommand(
{
type: 'go_to_file',
text: `Open file`,
altText: 'Open file',
handler: () => {
Expand All @@ -229,6 +233,7 @@ const addEditorCommandForRef = (args: {resourceMeta: ResourceMeta; ref: Resource
} else if (ref.target.type === 'image') {
command = addEditorCommand(
{
type: 'go_to_image',
text: `Open image`,
altText: 'Open image',
handler: () => {
Expand Down
10 changes: 10 additions & 0 deletions src/editor/enhancers/k8sResource/symbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ function addNamespaceFilterLink(
const namespace = getSymbolValue(lines, symbol);
if (namespace) {
const newCommand = addEditorCommand({
type: 'filter_namespace',
text: `Apply or remove`,
altText: 'Add/remove namespace to/from current filter',
handler: () => {
Expand All @@ -57,6 +58,7 @@ function addNamespaceFilterLink(
`);

addEditorHover({
type: 'list_namespace_filters',
range: symbol.range,
contents: [filterMarkdown],
});
Expand Down Expand Up @@ -88,6 +90,7 @@ function addKindFilterLink(
const kind = getSymbolValue(lines, symbol);
if (kind) {
const newCommand = addEditorCommand({
type: 'filter_kind',
text: `Apply or remove`,
altText: 'Add/remove kind to/from current filter',
handler: () => {
Expand All @@ -102,6 +105,7 @@ function addKindFilterLink(
`);

addEditorHover({
type: 'list_kind_filters',
range: symbol.range,
contents: [filterMarkdown],
});
Expand All @@ -121,6 +125,7 @@ function addLabelFilterLink(
const value = label.substring(symbol.name.length + 1).trim();

const newCommand = addEditorCommand({
type: 'filter_label',
text: `Apply or remove`,
altText: 'Add/remove label to/from current filter',
handler: () => {
Expand All @@ -137,6 +142,7 @@ function addLabelFilterLink(
`);

addEditorHover({
type: 'list_label_filters',
range: symbol.range,
contents: [filterMarkdown],
});
Expand All @@ -156,6 +162,7 @@ function addAnnotationFilterLink(
const value = annotation.substring(symbol.name.length + 1).trim();

const newCommand = addEditorCommand({
type: 'filter_annotation',
text: `${annotation}`,
altText: 'Add/remove annotation to/from current filter',
handler: () => {
Expand All @@ -172,6 +179,7 @@ function addAnnotationFilterLink(
`);

addEditorHover({
type: 'list_annotation_filters',
range: symbol.range,
contents: [filterMarkdown],
});
Expand All @@ -190,6 +198,7 @@ function addDecodeSecretHover(
const decoded = Buffer.from(value, 'base64').toString('utf-8');

const newCommand = addEditorCommand({
type: 'secret_copy_to_clipboard',
text: 'Copy to clipboard',
altText: 'Copy decoded secret to clipboard',
handler: () => {
Expand All @@ -204,6 +213,7 @@ function addDecodeSecretHover(
`);

addEditorHover({
type: 'decoded_secret',
range: symbol.range,
contents: [secretMarkdown],
});
Expand Down
29 changes: 29 additions & 0 deletions src/redux/services/clusterDashboard.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import * as k8s from '@kubernetes/client-node';

import {uniq} from 'lodash';

import {createKubeClientWithSetup} from '@redux/cluster/service/kube-client';

import {cpuParser, memoryParser} from '@utils/unit-converter';

import {isDefined} from '@shared/utils/filter';
import {trackEvent} from '@shared/utils/telemetry';

let lastContext: string | undefined;

export const getClusterUtilization = async (kubeconfig: string, context: string): Promise<NodeMetric[]> => {
const kc = await createKubeClientWithSetup({context, kubeconfig, skipHealthCheck: true});

Expand All @@ -13,6 +20,28 @@ export const getClusterUtilization = async (kubeconfig: string, context: string)

const nodeMetrics: k8s.NodeMetric[] = (await metricClient.getNodeMetrics()).items;
const nodes = await k8s.topNodes(k8sApiClient);
let kubeletVersion: string | undefined;

if (lastContext !== context) {
const providers = uniq(
nodes
.map(node => {
if (!kubeletVersion) {
kubeletVersion = node.Node.status?.nodeInfo?.kubeletVersion;
}

const providerId = node.Node?.spec?.providerID;
// ID of the node assigned by the cloud provider in the format: <ProviderName>://<ProviderSpecificNodeID>
const providerParts = providerId?.split('://');
if (providerParts?.length === 2) {
return providerParts[0];
}
return undefined;
})
.filter(isDefined)
);
trackEvent('cluster/info', {providers, kubeletVersion});
}

return nodeMetrics.map(m => ({
nodeName: m.metadata.name,
Expand Down
2 changes: 2 additions & 0 deletions src/redux/thunks/project/createProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {createProject} from '@redux/appConfig';
import {isFolderGitRepo} from '@redux/git/git.ipc';

import {Project} from '@shared/models/config';
import {trackEvent} from '@shared/utils/telemetry';

import {setOpenProject} from './openProject';

Expand All @@ -18,4 +19,5 @@ export const setCreateProject = createAsyncThunk('config/setCreateProject', asyn

thunkAPI.dispatch(createProject({...project, isGitRepo}));
thunkAPI.dispatch(setOpenProject(project.rootFolder));
trackEvent('app_start/create_project', {from: 'folder'});
});
4 changes: 2 additions & 2 deletions src/redux/thunks/runPreviewConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ export const runPreviewConfiguration = createAsyncThunk<

const result = await runCommandInMainThread(commandOptions);

if (result.error) {
trackEvent('preview/helm_config/fail', {reason: result.error});
if (result.error || result.stderr) {
trackEvent('preview/helm_config/fail', {reason: result.error || result.stderr || 'unknown'});
return createRejectionWithAlert(thunkAPI, 'Helm Error', `${result.error} - ${result.stderr}`);
}

Expand Down
Loading

0 comments on commit 34392c6

Please sign in to comment.