@grafana/faro-react
Version:
Faro package that enables easier integration in projects built with React.
84 lines • 3.46 kB
JavaScript
import { Component } from 'react';
import { VERSION } from '@grafana/faro-web-sdk';
import { api, internalLogger } from '../dependencies';
export class FaroProfiler extends Component {
get isOtelInitialized() {
return !!(api === null || api === void 0 ? void 0 : api.isOTELInitialized());
}
get otel() {
return api === null || api === void 0 ? void 0 : api.getOTEL();
}
get tracer() {
var _a;
return (_a = this.otel) === null || _a === void 0 ? void 0 : _a.trace.getTracer('@grafana/faro-react', VERSION);
}
createSpan(spanName, options) {
var _a, _b;
const span = this.tracer.startSpan(spanName, {
startTime: options === null || options === void 0 ? void 0 : options.startTime,
attributes: Object.assign({ 'react.component.name': this.props.name }, ((_a = options === null || options === void 0 ? void 0 : options.attributes) !== null && _a !== void 0 ? _a : {})),
});
(_b = this.otel) === null || _b === void 0 ? void 0 : _b.trace.setSpan(this.otel.context.active(), span);
if (options === null || options === void 0 ? void 0 : options.endTime) {
span.end(options.endTime);
}
return span;
}
createChildSpan(spanName, parent, options) {
var _a;
let span;
(_a = this.otel) === null || _a === void 0 ? void 0 : _a.context.with(this.otel.trace.setSpan(this.otel.context.active(), parent), () => {
span = this.createSpan(spanName, options);
});
return span;
}
constructor(props) {
super(props);
this.mountSpan = undefined;
this.mountSpanEndTime = undefined;
this.updateSpan = undefined;
if (this.isOtelInitialized) {
this.mountSpan = this.createSpan('componentMount');
}
else {
internalLogger === null || internalLogger === void 0 ? void 0 : internalLogger.error('The Faro React Profiler requires tracing instrumentation. Please enable it in the "instrumentations" section of your config.');
}
}
componentDidMount() {
if (this.isOtelInitialized && this.mountSpan) {
this.mountSpanEndTime = Date.now();
this.mountSpan.end(this.mountSpanEndTime);
}
}
shouldComponentUpdate({ updateProps }) {
if (this.isOtelInitialized && this.mountSpan && updateProps !== this.props.updateProps) {
const changedProps = Object.keys(updateProps).filter((key) => updateProps[key] !== this.props.updateProps[key]);
if (changedProps.length > 0) {
this.updateSpan = this.createChildSpan('componentUpdate', this.mountSpan, {
attributes: {
'react.component.changed_props': changedProps,
},
});
}
}
return true;
}
componentDidUpdate() {
if (this.isOtelInitialized && this.updateSpan) {
this.updateSpan.end();
this.updateSpan = undefined;
}
}
componentWillUnmount() {
if (this.isOtelInitialized && this.mountSpan) {
this.createChildSpan('componentRender', this.mountSpan, {
startTime: this.mountSpanEndTime,
endTime: Date.now(),
});
}
}
render() {
return this.props.children;
}
}
//# sourceMappingURL=FaroProfiler.js.map