这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,5 @@
- add meta descriptions to actions docs (#4082)
- `HASURA_GRAPHQL_EVENTS_FETCH_INTERVAL` changes semantics slightly: we only sleep for the interval
when there were previously no events to process. Potential space leak fixed. (#3839)
- console: track runtime errors (#4083)
- auto-include `__typename` field in custom types' objects (fix #4063)
45 changes: 28 additions & 17 deletions console/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import getRoutes from './routes';
import reducer from './reducer';
import globals from './Globals';
import Endpoints from './Endpoints';

import { filterEventsBlockList, sanitiseUrl } from './telemetryFilter';
import { RUN_TIME_ERROR } from './components/Main/Actions';

/** telemetry **/
let analyticsConnection;
Expand Down Expand Up @@ -57,46 +59,55 @@ function analyticsLogger({ getState }) {
return next => action => {
// Call the next dispatch method in the middleware chain.
const returnValue = next(action);

// check if analytics tracking is enabled
if (telemetryEnabled) {
const serverVersion = getState().main.serverVersion;
const actionType = action.type;
const url = sanitiseUrl(window.location.pathname);
const reqBody = {
server_version: serverVersion,
event_type: actionType,
url,
console_mode: consoleMode,
cli_uuid: cliUUID,
server_uuid: getState().telemetry.hasura_uuid,
};

let isLocationType = false;
if (actionType === '@@router/LOCATION_CHANGE') {
isLocationType = true;
}

// filter events
if (!filterEventsBlockList.includes(actionType)) {
// When the connection is open, send data to the server
if (
analyticsConnection &&
analyticsConnection.readyState === analyticsConnection.OPEN
) {
// When the connection is open, send data to the server
const serverVersion = getState().main.serverVersion;
const url = sanitiseUrl(window.location.pathname);

const reqBody = {
server_version: serverVersion,
event_type: actionType,
url,
console_mode: consoleMode,
cli_uuid: cliUUID,
server_uuid: getState().telemetry.hasura_uuid,
};

const isLocationType = actionType === '@@router/LOCATION_CHANGE';
if (isLocationType) {
// capture page views
const payload = action.payload;
reqBody.url = sanitiseUrl(payload.pathname);
}

const isErrorType = actionType === RUN_TIME_ERROR;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is an additional variable for that needed? It's only used once.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for readability and clarity I guess.

if (isErrorType) {
reqBody.data = action.data;
}

// Send the data
analyticsConnection.send(
JSON.stringify({ data: reqBody, topic: globals.telemetryTopic })
); // Send the data
);

// check for possible error events and store more data?
} else {
// retry websocket connection
// analyticsConnection = new WebSocket(analyticsUrl);
}
}
}

// This will likely be the action itself, unless
// a middleware further in chain changed it.
return returnValue;
Expand Down
6 changes: 6 additions & 0 deletions console/src/components/Error/ErrorBoundary.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Spinner from '../Common/Spinner/Spinner';

import PageNotFound, { NotFoundError } from './PageNotFound';
import RuntimeError from './RuntimeError';
import { registerRunTimeError } from '../Main/Actions';

class ErrorBoundary extends React.Component {
initialState = {
Expand Down Expand Up @@ -40,6 +41,11 @@ class ErrorBoundary extends React.Component {

this.setState({ hasError: true, info: info, error: error });

// trigger telemetry
dispatch(
registerRunTimeError({ message: error.message, stack: error.stack })
);

dispatch(loadInconsistentObjects(true)).then(() => {
if (this.props.metadata.inconsistentObjects.length > 0) {
if (!isMetadataStatusPage()) {
Expand Down
10 changes: 10 additions & 0 deletions console/src/components/Main/Actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const UPDATE_ADMIN_SECRET_INPUT = 'Main/UPDATE_ADMIN_SECRET_INPUT';
const LOGIN_IN_PROGRESS = 'Main/LOGIN_IN_PROGRESS';
const LOGIN_ERROR = 'Main/LOGIN_ERROR';

const RUN_TIME_ERROR = 'Main/RUN_TIME_ERROR';
const registerRunTimeError = data => ({
type: RUN_TIME_ERROR,
data,
});

/* Server config constants*/
const FETCHING_SERVER_CONFIG = 'Main/FETCHING_SERVER_CONFIG';
const SERVER_CONFIG_FETCH_SUCCESS = 'Main/SERVER_CONFIG_FETCH_SUCCESS';
Expand Down Expand Up @@ -273,6 +279,8 @@ const mainReducer = (state = defaultState, action) => {
return { ...state, loginInProgress: action.data };
case LOGIN_ERROR:
return { ...state, loginError: action.data };
case RUN_TIME_ERROR: // To trigger telemetry event
return state;
case FETCHING_SERVER_CONFIG:
return {
...state,
Expand Down Expand Up @@ -327,4 +335,6 @@ export {
fetchServerConfig,
loadLatestServerVersion,
featureCompatibilityInit,
RUN_TIME_ERROR,
registerRunTimeError,
};