1
\$\begingroup\$
//App.jsx
import React, { Component } from 'react';
import { initialiseLogger } from './logger';

class App extends Component {
  constructor(props) {
    super(props);
    initialiseLogger(props.environment);
  }
  render() {
    return (
      <Component />
    );
  }
}

export default App;

This it he top level of my React app. I initialise my logger here. And below is the logger. I am using our ui logger by my project. It exposes one function called configure that creates a logger based on some params. Each time it gets called it will create a new logger.

//logger.js
import LoggerFactory from '@company/ui-logger';
import appConfigurations from '../shared/appConfigurations';

const loggerContainer = {};

const initialiseLogger = (env) => {
  const url = appConfigurations.getLogUrl(env);
  const service = appConfigurations.getLogUrl(env);
  const version = appConfigurations.getComponentVersion(env);
  const apigeeClientId = appConfigurations.getComponentName(env);
  Object.freeze(
      Object.assign(
        loggerContainer,
        { logger: LoggerFactory.configure({ url, service, version, apigeeClientId }) }
      )
    );
  return loggerContainer.logger;
};
const getLogger = () => {
  if (!loggerContainer.logger) {
    // eslint-disable-next-line no-console
    console.error('A logger has not been initialised');
  }
  return loggerContainer.logger;
};

export { initialiseLogger, getLogger };

As you can see initialiseLogger gets some app config and creates a logger which then gets assigned inside a const object that then becomes immutable. I also expose a getLogger method that is going to be used in the other components to get the logger and then log what they want.

Example:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { getLogger } from '../logger';

class ErrorBox extends Component {
  constructor() {
    super();
    this.state = {
      isVisible: false,
      apiErrors: [],
      uiErrors: []
    };
    this.logger = getLogger();
  }

  componentDidMount() {
    ...
  }

  componentWillUnmount() {
    ...
  }

  updateErrorList = () => {
    ...
  }

  componentDidCatch(error) {
    this.setState({
      isVisible: true,
      uiErrors: [error]
    });

    this.logger.error(
      { message: error.message },
      error.stack
    );
  }


  render() {
    ...
  }
}

export default ErrorBox;

I am not feeling 100% sure about this code. Should I go for a singleton pattern and just expose the getLogger function.

Something like

import LoggerFactory from '@company/ui-logger';
import appConfigurations from '../shared/appConfigurations';

const loggerContainer = {};

const initialiseLogger = (env) => {
  const url = appConfigurations.getLogUrl(env);
  const service = appConfigurations.getLogUrl(env);
  const version = appConfigurations.getComponentVersion(env);
  const apigeeClientId = appConfigurations.getComponentName(env);
  Object.freeze(
      Object.assign(
        loggerContainer,
        { logger: LoggerFactory.configure({ url, service, version, apigeeClientId }) }
      )
    );
  return loggerContainer.logger;
};
const getLogger = () => {
  if (!loggerContainer.logger) {
    initialiseLogger('env');
  }
  return loggerContainer.logger;
};

export default getLogger;

Or even

import LoggerFactory from '@company/ui-logger';
import appConfigurations from '../shared/appConfigurations';

const Logger = () => {
  let instance;

  const initialiseLogger = (env) => {
    const url = appConfigurations.getLogUrl(env);
    const service = appConfigurations.getLogUrl(env);
    const version = appConfigurations.getComponentVersion(env);
    const apigeeClientId = appConfigurations.getComponentName(env);
    return LoggerFactory.configure({ url, service, version, apigeeClientId });
  };

  return {
    getLogger() {
      if (!instance) {
        instance = initialiseLogger('env');
      }
      return instance;
    }
  };
};

export default Logger();

But i am not sure about my design of this singleton. Would the instance be visble to getLogger when I export it as a module to another compoent?

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.