Implement Zaqar logger adapter
Implements: blueprint websocket-logging Change-Id: Ie5e2554b54512ee0b590efa57a4269806b0f9294
This commit is contained in:
parent
1c665a1d50
commit
8420610ec2
|
@ -24,5 +24,6 @@ window.tripleOUiConfig = {
|
|||
// 'excludedLanguages': ['de', 'ja'],
|
||||
|
||||
// Logging
|
||||
// 'loggers': ['console']
|
||||
// 'loggers': ['console', 'zaqar']
|
||||
// 'logger-zaqar-queue': 'tripleo-ui-logging'
|
||||
};
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Implements `websocket-logging <https://blueprints.launchpad.net/openstack/?searchtext=websocket-logging>`__
|
||||
Implement Zaqar logger adapter
|
|
@ -19,10 +19,10 @@ import { Map } from 'immutable';
|
|||
import React from 'react';
|
||||
import ReactShallowRenderer from 'react-test-renderer/shallow';
|
||||
|
||||
import store from '../../../js/store';
|
||||
import PlansList from '../../../js/components/plan/PlansList';
|
||||
import FileList from '../../../js/components/plan/FileList';
|
||||
import { PlanFile } from '../../../js/immutableRecords/plans';
|
||||
import store from '../../../js/store';
|
||||
|
||||
describe('PlansList component', () => {
|
||||
let output;
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* Copyright 2017 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { List, Map } from 'immutable';
|
||||
|
||||
import { InitialLoggerState } from '../../js/immutableRecords/logger';
|
||||
import LoggerActions from '../../js/actions/LoggerActions';
|
||||
import loggerReducer from '../../js/reducers/loggerReducer';
|
||||
|
||||
describe('loggerReducer state', () => {
|
||||
describe('default state', () => {
|
||||
let state;
|
||||
|
||||
beforeEach(() => {
|
||||
state = loggerReducer(undefined, { type: 'undefined-action' });
|
||||
});
|
||||
|
||||
it('`authenticated` is false', () => {
|
||||
expect(state.get('authenticated')).toBe(false);
|
||||
});
|
||||
|
||||
it('`messages` is empty', () => {
|
||||
expect(state.get('messages').isEmpty()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('QUEUE_MESSAGE', () => {
|
||||
it('enqueues a messages', () => {
|
||||
let state = loggerReducer(
|
||||
new InitialLoggerState(),
|
||||
LoggerActions.queueMessage(1)
|
||||
);
|
||||
expect(state.get('messages').size).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('FLUSH_MESSAGES_SUCCESS', () => {
|
||||
it('flushes messages', () => {
|
||||
let state = loggerReducer(
|
||||
Map({
|
||||
messages: List([1, 2, 3]),
|
||||
authenticated: true
|
||||
}),
|
||||
LoggerActions.flushMessagesSuccess()
|
||||
);
|
||||
|
||||
expect(state.get('messages').isEmpty()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -25,7 +25,7 @@ import NotificationActions from '../actions/NotificationActions';
|
|||
import MistralApiErrorHandler from '../services/MistralApiErrorHandler';
|
||||
import { topicSchema } from '../normalizrSchemas/environmentConfiguration';
|
||||
import MistralConstants from '../constants/MistralConstants';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
import SwiftApiErrorHandler from '../services/SwiftApiErrorHandler';
|
||||
import SwiftApiService from '../services/SwiftApiService';
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Copyright 2017 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import when from 'when';
|
||||
import LoggerConstants from '../constants/LoggerConstants';
|
||||
import ZaqarWebSocketService from '../services/ZaqarWebSocketService';
|
||||
import NotificationActions from '../actions/NotificationActions';
|
||||
|
||||
export default {
|
||||
queueMessage(message) {
|
||||
return {
|
||||
type: LoggerConstants.QUEUE_MESSAGE,
|
||||
payload: message
|
||||
};
|
||||
},
|
||||
|
||||
flushMessagesSuccess() {
|
||||
return {
|
||||
type: LoggerConstants.FLUSH_MESSAGES_SUCCESS
|
||||
};
|
||||
},
|
||||
|
||||
flushMessages() {
|
||||
return (dispatch, getState) => {
|
||||
const messages = getState().logger.messages;
|
||||
|
||||
when
|
||||
.all(() => {
|
||||
messages.map(message => {
|
||||
ZaqarWebSocketService.sendMessage('message_post', message);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
dispatch(this.flushMessagesSuccess());
|
||||
})
|
||||
.catch(error => {
|
||||
// We're using `console` here to avoid circular imports.
|
||||
console.error(error); // eslint-disable-line no-console
|
||||
dispatch(
|
||||
NotificationActions.notify({
|
||||
title: 'Logging error',
|
||||
message: 'Failed to flush Zaqar messages.'
|
||||
})
|
||||
);
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
authenticated() {
|
||||
return {
|
||||
type: LoggerConstants.WS_AUTHENTICATION_SUCCESS
|
||||
};
|
||||
}
|
||||
};
|
|
@ -20,7 +20,7 @@ import KeystoneApiErrorHandler from '../services/KeystoneApiErrorHandler';
|
|||
import KeystoneApiService from '../services/KeystoneApiService';
|
||||
import LoginConstants from '../constants/LoginConstants';
|
||||
import ZaqarWebSocketService from '../services/ZaqarWebSocketService';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
import cookie from 'react-cookie';
|
||||
|
||||
export default {
|
||||
|
|
|
@ -34,7 +34,7 @@ import {
|
|||
introspectionStatusSchema
|
||||
} from '../normalizrSchemas/nodes';
|
||||
import MistralConstants from '../constants/MistralConstants';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
import { setNodeCapability } from '../utils/nodes';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
|
|
@ -22,7 +22,7 @@ import ParametersConstants from '../constants/ParametersConstants';
|
|||
import MistralApiService from '../services/MistralApiService';
|
||||
import MistralApiErrorHandler from '../services/MistralApiErrorHandler';
|
||||
import MistralConstants from '../constants/MistralConstants';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
|
||||
const messages = defineMessages({
|
||||
parametersUpdatedNotficationTitle: {
|
||||
|
|
|
@ -19,7 +19,7 @@ import { fromJS } from 'immutable';
|
|||
import { normalize, arrayOf } from 'normalizr';
|
||||
import when from 'when';
|
||||
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
import MistralApiService from '../services/MistralApiService';
|
||||
import MistralApiErrorHandler from '../services/MistralApiErrorHandler';
|
||||
import NotificationActions from '../actions/NotificationActions';
|
||||
|
|
|
@ -27,7 +27,7 @@ import NodesActions from './NodesActions';
|
|||
import { nodeSchema } from '../normalizrSchemas/nodes';
|
||||
import ValidationsActions from './ValidationsActions';
|
||||
import MistralConstants from '../constants/MistralConstants';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
|
||||
const messages = defineMessages({
|
||||
registrationNotificationTitle: {
|
||||
|
|
|
@ -19,7 +19,7 @@ import RolesConstants from '../constants/RolesConstants';
|
|||
import MistralApiService from '../services/MistralApiService';
|
||||
import MistralApiErrorHandler from '../services/MistralApiErrorHandler';
|
||||
import MistralConstants from '../constants/MistralConstants';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
|
||||
export default {
|
||||
fetchRoles(planName) {
|
||||
|
|
|
@ -21,7 +21,7 @@ import HeatApiService from '../services/HeatApiService';
|
|||
import NotificationActions from '../actions/NotificationActions';
|
||||
import StacksConstants from '../constants/StacksConstants';
|
||||
import { stackSchema, stackResourceSchema } from '../normalizrSchemas/stacks';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
|
||||
export default {
|
||||
fetchStacksPending() {
|
||||
|
|
|
@ -24,7 +24,7 @@ import MistralApiErrorHandler from '../services/MistralApiErrorHandler';
|
|||
import ValidationsConstants from '../constants/ValidationsConstants';
|
||||
import { validationSchema } from '../normalizrSchemas/validations';
|
||||
import MistralConstants from '../constants/MistralConstants';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
|
||||
export default {
|
||||
fetchValidations() {
|
||||
|
|
|
@ -24,7 +24,7 @@ import WorkflowExecutionsConstants
|
|||
import {
|
||||
workflowExecutionSchema
|
||||
} from '../normalizrSchemas/workflowExecutions';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
|
||||
export default {
|
||||
fetchWorkflowExecutions() {
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { get } from 'lodash';
|
||||
import LoggerActions from './LoggerActions';
|
||||
import NodesActions from './NodesActions';
|
||||
import PlansActions from './PlansActions';
|
||||
import RegisterNodesActions from './RegisterNodesActions';
|
||||
|
@ -28,8 +30,18 @@ export default {
|
|||
};
|
||||
},
|
||||
|
||||
handleAuthenticationSuccess(message, dispatch) {
|
||||
message = get(message, ['body', 'message']);
|
||||
|
||||
if (message === 'Authentified.') {
|
||||
dispatch(LoggerActions.authenticated());
|
||||
dispatch(LoggerActions.flushMessages());
|
||||
}
|
||||
},
|
||||
|
||||
messageReceived(message, history) {
|
||||
return (dispatch, getState) => {
|
||||
this.handleAuthenticationSuccess(message, dispatch);
|
||||
const { type, payload } = message.body;
|
||||
switch (type) {
|
||||
case MistralConstants.BAREMETAL_REGISTER_OR_UPDATE:
|
||||
|
@ -74,5 +86,31 @@ export default {
|
|||
break;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
postMessage(queueName, body, ttl = 3600) {
|
||||
return (dispatch, getState) => {
|
||||
const message = {
|
||||
queue_name: queueName,
|
||||
messages: [
|
||||
{
|
||||
body,
|
||||
ttl
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Drop the message on the floor when there is no `store`
|
||||
if (!getState) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getState().logger.authenticated) {
|
||||
dispatch(LoggerActions.queueMessage(message));
|
||||
return;
|
||||
}
|
||||
|
||||
ZaqarWebSocketService.sendMessage('message_post', message);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -42,9 +42,9 @@ const messages = defineMessages({
|
|||
|
||||
class AuthenticatedContent extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.initializeZaqarConnection();
|
||||
this.props.fetchPlans();
|
||||
this.props.fetchWorkflowExecutions();
|
||||
this.props.initializeZaqarConnection();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Copyright 2017 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import keyMirror from 'keymirror';
|
||||
|
||||
export default keyMirror({
|
||||
QUEUE_MESSAGE: null,
|
||||
FLUSH_MESSAGES_SUCCESS: null,
|
||||
WS_AUTHENTICATION_SUCCESS: null
|
||||
});
|
|
@ -14,8 +14,11 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
let appConfig = window.tripleOUiConfig || {};
|
||||
import { getAppConfig } from '../services/utils';
|
||||
|
||||
let zaqarDefaultQueue = appConfig.zaqar_default_queue || 'tripleo';
|
||||
let zaqarDefaultQueue = getAppConfig()['zaqar_default_queue'] || 'tripleo';
|
||||
let zaqarLoggingQueue =
|
||||
getAppConfig()['logger-zaqar-queue'] || 'tripleo-ui-logging';
|
||||
|
||||
export const ZAQAR_DEFAULT_QUEUE = zaqarDefaultQueue;
|
||||
export const ZAQAR_LOGGING_QUEUE = zaqarLoggingQueue;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Copyright 2017 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { List, Record } from 'immutable';
|
||||
|
||||
export const InitialLoggerState = Record({
|
||||
messages: List(),
|
||||
authenticated: false
|
||||
});
|
|
@ -20,6 +20,7 @@ import { reducer as formReducer } from 'redux-form';
|
|||
import environmentConfigurationReducer from './environmentConfigurationReducer';
|
||||
import filtersReducer from './filtersReducer';
|
||||
import i18nReducer from './i18nReducer';
|
||||
import loggerReducer from './loggerReducer';
|
||||
import loginReducer from './loginReducer';
|
||||
import nodesReducer from './nodesReducer';
|
||||
import notificationsReducer from './notificationsReducer';
|
||||
|
@ -36,6 +37,7 @@ const appReducer = combineReducers({
|
|||
executions: workflowExecutionsReducer,
|
||||
filters: filtersReducer,
|
||||
i18n: i18nReducer,
|
||||
logger: loggerReducer,
|
||||
login: loginReducer,
|
||||
nodes: nodesReducer,
|
||||
notifications: notificationsReducer,
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Copyright 2017 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { List } from 'immutable';
|
||||
import { InitialLoggerState } from '../immutableRecords/logger';
|
||||
import LoggerConstants from '../constants/LoggerConstants';
|
||||
|
||||
const initialState = new InitialLoggerState();
|
||||
|
||||
export default function loggerReduder(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case LoggerConstants.QUEUE_MESSAGE:
|
||||
return state.update('messages', messages =>
|
||||
messages.push(action.payload)
|
||||
);
|
||||
|
||||
case LoggerConstants.WS_AUTHENTICATION_SUCCESS:
|
||||
return state.set('authenticated', true);
|
||||
|
||||
case LoggerConstants.FLUSH_MESSAGES_SUCCESS:
|
||||
return state.set('messages', List());
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ import request from 'reqwest';
|
|||
import when from 'when';
|
||||
|
||||
import { getAuthTokenId, getServiceUrl } from '../services/utils';
|
||||
import logger from '../services/logger';
|
||||
import logger from '../services/logging/LoggingService';
|
||||
|
||||
class SwiftApiService {
|
||||
defaultRequest(path, additionalAttributes) {
|
||||
|
|
|
@ -21,7 +21,13 @@ import { getAuthTokenId, getProjectId, getServiceUrl } from './utils';
|
|||
import { ZAQAR_DEFAULT_QUEUE } from '../constants/ZaqarConstants';
|
||||
import ZaqarActions from '../actions/ZaqarActions';
|
||||
import NotificationActions from '../actions/NotificationActions';
|
||||
import logger from '../services/logger';
|
||||
|
||||
// We're using `console` here to avoid circular imports.
|
||||
const logger = {
|
||||
error: (...msg) => {
|
||||
console.log(...msg); // eslint-disable-line no-console
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
socket: null,
|
||||
|
@ -55,7 +61,8 @@ export default {
|
|||
};
|
||||
|
||||
this.socket.onmessage = evt => {
|
||||
dispatch(ZaqarActions.messageReceived(JSON.parse(evt.data), history));
|
||||
const data = JSON.parse(evt.data);
|
||||
dispatch(ZaqarActions.messageReceived(data, history));
|
||||
};
|
||||
});
|
||||
},
|
||||
|
|
|
@ -25,66 +25,17 @@
|
|||
//
|
||||
// Usage:
|
||||
//
|
||||
// import logger from 'src/js/services/logger';
|
||||
// import logger from 'src/js/services/logging/LoggingService';
|
||||
// logger.log('Hello world!');
|
||||
|
||||
class Adapter {
|
||||
debug(...args) {}
|
||||
|
||||
info(...args) {}
|
||||
|
||||
warn(...args) {}
|
||||
|
||||
error(...args) {}
|
||||
|
||||
group(...args) {}
|
||||
|
||||
groupCollapsed(...args) {}
|
||||
|
||||
groupEnd(...args) {}
|
||||
|
||||
log(...args) {}
|
||||
}
|
||||
|
||||
class ConsoleAdapter extends Adapter {
|
||||
debug(...args) {
|
||||
console.debug(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
info(...args) {
|
||||
console.info(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
warn(...args) {
|
||||
console.warn(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
error(...args) {
|
||||
console.error(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
group(...args) {
|
||||
console.group(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
groupCollapsed(...args) {
|
||||
console.groupCollapsed(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
groupEnd(...args) {
|
||||
console.groupEnd(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
log(...args) {
|
||||
console.log(...args); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
|
||||
class ZaqarAdapter extends Adapter {}
|
||||
import { includes } from 'lodash';
|
||||
import LoggerConstants from '../../constants/LoggerConstants';
|
||||
import ConsoleAdapter from './adapters/ConsoleAdapter';
|
||||
import ZaqarAdapter from './adapters/ZaqarAdapter';
|
||||
|
||||
const AVAILABLE_ADAPTERS = {
|
||||
console: new ConsoleAdapter(),
|
||||
zaqar: new ZaqarAdapter()
|
||||
console: ConsoleAdapter,
|
||||
zaqar: ZaqarAdapter
|
||||
};
|
||||
|
||||
class Logger {
|
||||
|
@ -101,10 +52,7 @@ class Logger {
|
|||
|
||||
constructor() {
|
||||
this.adapters = [];
|
||||
|
||||
if (window.tripleOUiConfig !== undefined) {
|
||||
this.loadAdapters();
|
||||
}
|
||||
this.reduxDispatch = null;
|
||||
|
||||
this.AVAILABLE_FUNCTIONS.forEach(fn => {
|
||||
this[fn] = function(...args) {
|
||||
|
@ -115,19 +63,20 @@ class Logger {
|
|||
this.registerGlobalErrorHandler();
|
||||
}
|
||||
|
||||
setReduxDispatch(dispatchFunction) {
|
||||
this.reduxDispatch = dispatchFunction;
|
||||
this.loadAdapters();
|
||||
}
|
||||
|
||||
loadAdapters() {
|
||||
if (this.adapters.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.tripleOUiConfig === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let enabledAdapters = window.tripleOUiConfig.loggers || ['console'];
|
||||
let enabledAdapters = (window.tripleOUiConfig || {}).loggers || ['console'];
|
||||
|
||||
enabledAdapters.forEach(adapter => {
|
||||
let instance = AVAILABLE_ADAPTERS[adapter];
|
||||
let instance = new AVAILABLE_ADAPTERS[adapter](this.reduxDispatch);
|
||||
|
||||
if (instance === undefined) {
|
||||
throw Error(`Adapter ${adapter} not defined`);
|
||||
|
@ -138,8 +87,6 @@ class Logger {
|
|||
}
|
||||
|
||||
dispatch(fn, ...args) {
|
||||
this.loadAdapters();
|
||||
|
||||
this.adapters.forEach(adapter => {
|
||||
let f = adapter[fn];
|
||||
|
||||
|
@ -159,4 +106,11 @@ class Logger {
|
|||
}
|
||||
}
|
||||
|
||||
const isLoggerAction = action => includes(LoggerConstants, action.type);
|
||||
|
||||
// The `predicate` prevents redux-logger from logging logger messages
|
||||
// in order to avoid an infinite loop. This function is used in `createLogger`
|
||||
// in store.js.
|
||||
export const predicate = (getState, action) => !isLoggerAction(action);
|
||||
|
||||
export default new Logger();
|
|
@ -0,0 +1,21 @@
|
|||
export default class Adapter {
|
||||
constructor(dispatch) {
|
||||
this._dispatch = dispatch;
|
||||
}
|
||||
|
||||
debug(...args) {}
|
||||
|
||||
info(...args) {}
|
||||
|
||||
warn(...args) {}
|
||||
|
||||
error(...args) {}
|
||||
|
||||
group(...args) {}
|
||||
|
||||
groupCollapsed(...args) {}
|
||||
|
||||
groupEnd(...args) {}
|
||||
|
||||
log(...args) {}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import Adapter from './BaseAdapter';
|
||||
|
||||
export default class ConsoleAdapter extends Adapter {
|
||||
debug(...args) {
|
||||
console.debug(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
info(...args) {
|
||||
console.info(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
warn(...args) {
|
||||
console.warn(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
error(...args) {
|
||||
console.error(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
group(...args) {
|
||||
console.group(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
groupCollapsed(...args) {
|
||||
console.groupCollapsed(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
groupEnd(...args) {
|
||||
console.groupEnd(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
log(...args) {
|
||||
console.log(...args); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
import { ZAQAR_LOGGING_QUEUE } from '../../../constants/ZaqarConstants';
|
||||
import ZaqarActions from '../../../actions/ZaqarActions';
|
||||
import Adapter from './BaseAdapter';
|
||||
|
||||
export default class ZaqarAdapter extends Adapter {
|
||||
constructor(dispatch) {
|
||||
super(dispatch);
|
||||
this.indent = 0;
|
||||
this.buffer = [];
|
||||
}
|
||||
|
||||
_formatMessage(message, level) {
|
||||
return {
|
||||
message,
|
||||
level,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
}
|
||||
|
||||
_send(message, level) {
|
||||
if (this.indent !== 0) {
|
||||
this.buffer.push({
|
||||
message,
|
||||
level
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const msg = this._formatMessage(message[0], level);
|
||||
this._dispatch(ZaqarActions.postMessage(ZAQAR_LOGGING_QUEUE, msg));
|
||||
}
|
||||
|
||||
debug(...args) {
|
||||
this._send(args, 'debug');
|
||||
}
|
||||
|
||||
info(...args) {
|
||||
this._send(args, 'info');
|
||||
}
|
||||
|
||||
warn(...args) {
|
||||
this._send(args, 'warn');
|
||||
}
|
||||
|
||||
error(...args) {
|
||||
this._send(args, 'error');
|
||||
}
|
||||
|
||||
group(...args) {
|
||||
this.indent++;
|
||||
}
|
||||
|
||||
groupCollapsed(...args) {
|
||||
this.indent++;
|
||||
}
|
||||
|
||||
groupEnd(...args) {
|
||||
this.indent--;
|
||||
|
||||
this.buffer.map(m => {
|
||||
this._send(m.message, m.level);
|
||||
});
|
||||
|
||||
this.buffer = [];
|
||||
}
|
||||
|
||||
log(...args) {
|
||||
this.info(args);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ import { applyMiddleware, createStore } from 'redux';
|
|||
import cookie from 'react-cookie';
|
||||
import thunkMiddleware from 'redux-thunk';
|
||||
import createLogger from 'redux-logger';
|
||||
import logger from './services/logger';
|
||||
import logger, { predicate } from './services/logging/LoggingService';
|
||||
|
||||
import appReducer from './reducers/appReducer';
|
||||
import { InitialPlanState } from './immutableRecords/plans';
|
||||
|
@ -44,7 +44,17 @@ function getStoredPlanName() {
|
|||
|
||||
const loggerMiddleware = createLogger({
|
||||
collapsed: true,
|
||||
logger: logger
|
||||
predicate: predicate,
|
||||
logger: logger,
|
||||
// We're turning off all colors here because the formatting chars obscure the
|
||||
// content server-side.
|
||||
colors: {
|
||||
title: false,
|
||||
prevState: false,
|
||||
action: false,
|
||||
nextState: false,
|
||||
error: false
|
||||
}
|
||||
});
|
||||
|
||||
const store = createStore(
|
||||
|
@ -56,4 +66,6 @@ const store = createStore(
|
|||
)
|
||||
);
|
||||
|
||||
logger.setReduxDispatch(store.dispatch);
|
||||
|
||||
export default store;
|
||||
|
|
Loading…
Reference in New Issue