Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

createLogger.js.flow 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // @flow
  2. import environmentIsNode from 'detect-node';
  3. import createGlobalThis from 'globalthis';
  4. import stringify from 'json-stringify-safe';
  5. import {
  6. sprintf,
  7. } from 'sprintf-js';
  8. import {
  9. logLevels,
  10. } from '../constants';
  11. import type {
  12. LoggerType,
  13. MessageContextType,
  14. MessageEventHandlerType,
  15. TranslateMessageFunctionType,
  16. } from '../types';
  17. const globalThis = createGlobalThis();
  18. let domain;
  19. if (environmentIsNode) {
  20. // eslint-disable-next-line global-require
  21. domain = require('domain');
  22. }
  23. const getParentDomainContext = () => {
  24. if (!domain) {
  25. return {};
  26. }
  27. const parentRoarrContexts = [];
  28. let currentDomain = process.domain;
  29. // $FlowFixMe
  30. if (!currentDomain || !currentDomain.parentDomain) {
  31. return {};
  32. }
  33. while (currentDomain && currentDomain.parentDomain) {
  34. currentDomain = currentDomain.parentDomain;
  35. if (currentDomain.roarr && currentDomain.roarr.context) {
  36. parentRoarrContexts.push(currentDomain.roarr.context);
  37. }
  38. }
  39. let domainContext = {};
  40. for (const parentRoarrContext of parentRoarrContexts) {
  41. domainContext = {
  42. ...domainContext,
  43. ...parentRoarrContext,
  44. };
  45. }
  46. return domainContext;
  47. };
  48. const getFirstParentDomainContext = () => {
  49. if (!domain) {
  50. return {};
  51. }
  52. let currentDomain = process.domain;
  53. // $FlowFixMe
  54. if (currentDomain && currentDomain.roarr && currentDomain.roarr.context) {
  55. return currentDomain.roarr.context;
  56. }
  57. // $FlowFixMe
  58. if (!currentDomain || !currentDomain.parentDomain) {
  59. return {};
  60. }
  61. while (currentDomain && currentDomain.parentDomain) {
  62. currentDomain = currentDomain.parentDomain;
  63. if (currentDomain.roarr && currentDomain.roarr.context) {
  64. return currentDomain.roarr.context;
  65. }
  66. }
  67. return {};
  68. };
  69. const createLogger = (onMessage: MessageEventHandlerType, parentContext?: MessageContextType): LoggerType => {
  70. // eslint-disable-next-line id-length, unicorn/prevent-abbreviations
  71. const log = (a, b, c, d, e, f, g, h, i, k) => {
  72. const time = Date.now();
  73. const sequence = globalThis.ROARR.sequence++;
  74. let context;
  75. let message;
  76. if (typeof a === 'string') {
  77. context = {
  78. ...getFirstParentDomainContext(),
  79. ...parentContext || {},
  80. };
  81. // eslint-disable-next-line id-length, object-property-newline
  82. const {...args} = {a, b, c, d, e, f, g, h, i, k};
  83. const values = Object.keys(args).map((key) => {
  84. return args[key];
  85. });
  86. // eslint-disable-next-line unicorn/no-reduce
  87. const hasOnlyOneParameterValued = 1 === values.reduce((accumulator, value) => {
  88. // eslint-disable-next-line no-return-assign, no-param-reassign
  89. return accumulator += typeof value === 'undefined' ? 0 : 1;
  90. }, 0);
  91. message = hasOnlyOneParameterValued ? sprintf('%s', a) : sprintf(a, b, c, d, e, f, g, h, i, k);
  92. } else {
  93. if (typeof b !== 'string') {
  94. throw new TypeError('Message must be a string.');
  95. }
  96. context = JSON.parse(stringify({
  97. ...getFirstParentDomainContext(),
  98. ...parentContext || {},
  99. ...a,
  100. }));
  101. message = sprintf(b, c, d, e, f, g, h, i, k);
  102. }
  103. onMessage({
  104. context,
  105. message,
  106. sequence,
  107. time,
  108. version: '1.0.0',
  109. });
  110. };
  111. log.child = (context: TranslateMessageFunctionType | MessageContextType): LoggerType => {
  112. if (typeof context === 'function') {
  113. return createLogger((message) => {
  114. if (typeof context !== 'function') {
  115. throw new TypeError('Unexpected state.');
  116. }
  117. onMessage(context(message));
  118. }, parentContext);
  119. }
  120. return createLogger(onMessage, {
  121. ...getFirstParentDomainContext(),
  122. ...parentContext,
  123. ...context,
  124. });
  125. };
  126. log.getContext = (): MessageContextType => {
  127. return {
  128. ...getFirstParentDomainContext(),
  129. ...parentContext || {},
  130. };
  131. };
  132. log.adopt = async (routine, context) => {
  133. if (!domain) {
  134. return routine();
  135. }
  136. const adoptedDomain = domain.create();
  137. return adoptedDomain
  138. .run(() => {
  139. // $FlowFixMe
  140. adoptedDomain.roarr = {
  141. context: {
  142. ...getParentDomainContext(),
  143. ...context,
  144. },
  145. };
  146. return routine();
  147. });
  148. };
  149. for (const logLevel of Object.keys(logLevels)) {
  150. // eslint-disable-next-line id-length, unicorn/prevent-abbreviations
  151. log[logLevel] = (a, b, c, d, e, f, g, h, i, k) => {
  152. return log.child({
  153. logLevel: logLevels[logLevel],
  154. })(a, b, c, d, e, f, g, h, i, k);
  155. };
  156. }
  157. // @see https://github.com/facebook/flow/issues/6705
  158. // $FlowFixMe
  159. return log;
  160. };
  161. export default createLogger;