UNPKG

@loopback/docs

Version:
823 lines (720 loc) 52.2 kB
<!DOCTYPE html> <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> <!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/code-themes/sl-theme.css"> <link rel="stylesheet" href="css/main.css"> </head> <body> <div class="navbar navbar-inverse navbar-static-top" role="navigation"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">docs.strongloop.com</a> </div> <div id="modules"></div> </div> <div class="row"> <div class="col-lg-3 column scroll-spy-target"> <ul class="nav nav-pills nav-stacked"> <div id="versions"></div> <li class="depth-1"> <a href="#change-log">Change Log</a> </li> <li class="depth-2"> <a href="#0-9-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-9-0-loopback-example-log-extension-0-9-1-2018-05-08">0.9.1</a> </li> <li class="depth-1"> <a href="#0-9-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-3-loopback-example-log-extension-0-9-0-2018-05-03">0.9.0</a> </li> <li class="depth-3"> <a href="#features">Features</a> </li> <li class="depth-1"> <a href="#0-8-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-3-loopback-example-log-extension-0-8-0-2018-05-03">0.8.0</a> </li> <li class="depth-3"> <a href="#features-1">Features</a> </li> <li class="depth-2"> <a href="#0-7-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-2-loopback-example-log-extension-0-7-3-2018-04-26">0.7.3</a> </li> <li class="depth-2"> <a href="#0-7-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-1-loopback-example-log-extension-0-7-2-2018-04-26">0.7.2</a> </li> <li class="depth-2"> <a href="#0-7-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-0-loopback-example-log-extension-0-7-1-2018-04-25">0.7.1</a> </li> <li class="depth-1"> <a href="#0-7-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-3-loopback-example-log-extension-0-7-0-2018-04-16">0.7.0</a> </li> <li class="depth-2"> <a href="#0-6-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-2-loopback-example-log-extension-0-6-3-2018-04-16">0.6.3</a> </li> <li class="depth-2"> <a href="#0-6-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-1-loopback-example-log-extension-0-6-2-2018-04-12">0.6.2</a> </li> <li class="depth-2"> <a href="#0-6-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-0-loopback-example-log-extension-0-6-1-2018-04-11">0.6.1</a> </li> <li class="depth-1"> <a href="#0-6-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-2-loopback-example-log-extension-0-6-0-2018-04-11">0.6.0</a> </li> <li class="depth-3"> <a href="#bug-fixes">Bug Fixes</a> </li> <li class="depth-3"> <a href="#features-2">Features</a> </li> <li class="depth-2"> <a href="#0-5-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-2-loopback-example-log-extension-0-5-3-2018-04-06">0.5.3</a> </li> <li class="depth-2"> <a href="#0-5-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-1-loopback-example-log-extension-0-5-2-2018-04-04">0.5.2</a> </li> <li class="depth-2"> <a href="#0-5-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-0-loopback-example-log-extension-0-5-1-2018-04-02">0.5.1</a> </li> <li class="depth-1"> <a href="#0-5-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-4-1-loopback-example-log-extension-0-5-0-2018-03-29">0.5.0</a> </li> <li class="depth-3"> <a href="#code-refactoring">Code Refactoring</a> </li> <li class="depth-3"> <a href="#breaking-changes">BREAKING CHANGES</a> </li> <li class="depth-2"> <a href="#0-4-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-4-0-loopback-example-log-extension-0-4-1-2018-03-23">0.4.1</a> </li> <li class="depth-1"> <a href="#0-4-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-4-loopback-example-log-extension-0-4-0-2018-03-21">0.4.0</a> </li> <li class="depth-3"> <a href="#features-3">Features</a> </li> <li class="depth-3"> <a href="#breaking-changes-1">BREAKING CHANGES</a> </li> <li class="depth-2"> <a href="#0-3-4-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-3-loopback-example-log-extension-0-3-4-2018-03-14">0.3.4</a> </li> <li class="depth-2"> <a href="#0-3-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-2-loopback-example-log-extension-0-3-3-2018-03-13">0.3.3</a> </li> <li class="depth-2"> <a href="#0-3-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-1-loopback-example-log-extension-0-3-2-2018-03-08">0.3.2</a> </li> <li class="depth-2"> <a href="#0-3-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-0-loopback-example-log-extension-0-3-1-2018-03-07">0.3.1</a> </li> <li class="depth-1"> <a href="#0-3-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-2-0-loopback-example-log-extension-0-3-0-2018-03-06">0.3.0</a> </li> <li class="depth-3"> <a href="#features-4">Features</a> </li> <li class="depth-1"> <a href="#0-2-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-1-2-loopback-example-log-extension-0-2-0-2018-03-01">0.2.0</a> </li> <li class="depth-2"> <a href="#0-1-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-1-1-loopback-example-log-extension-0-1-2-2018-03-01">0.1.2</a> </li> <li class="depth-2"> <a href="#0-1-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-1-0-loopback-example-log-extension-0-1-1-2018-02-23">0.1.1</a> </li> <li class="depth-1"> <a href="#0-1-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-7-loopback-example-log-extension-0-1-0-2018-02-21">0.1.0</a> </li> <li class="depth-1"> <a href="#4-0-0-alpha-7-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-6-loopback-example-log-extension-4-0-0-alpha-7-2018-02-15">4.0.0-alpha.7</a> </li> <li class="depth-3"> <a href="#bug-fixes-1">Bug Fixes</a> </li> <li class="depth-1"> <a href="#4-0-0-alpha-6-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-5-loopback-example-log-extension-4-0-0-alpha-6-2018-02-07">4.0.0-alpha.6</a> </li> <li class="depth-3"> <a href="#build">build</a> </li> <li class="depth-3"> <a href="#breaking-changes-2">BREAKING CHANGES</a> </li> <li class="depth-1"> <a href="#4-0-0-alpha-5-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-4-loopback-example-log-extension-4-0-0-alpha-5-2018-02-04">4.0.0-alpha.5</a> </li> <li class="depth-3"> <a href="#bug-fixes-2">Bug Fixes</a> </li> <li class="depth-1"> <a href="#4-0-0-alpha-4-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-3-loopback-example-log-extension-4-0-0-alpha-4-2018-01-30">4.0.0-alpha.4</a> </li> <li class="depth-1"> <a href="#4-0-0-alpha-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-2-loopback-example-log-extension-4-0-0-alpha-3-2018-01-29">4.0.0-alpha.3</a> </li> <li class="depth-1"> <a href="#4-0-0-alpha-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-1-loopback-example-log-extension-4-0-0-alpha-2-2018-01-26">4.0.0-alpha.2</a> </li> <li class="depth-1"> <a href="#4-0-0-alpha-1-2018-01-26">4.0.0-alpha.1</a> </li> <li class="depth-3"> <a href="#bug-fixes-3">Bug Fixes</a> </li> <li class="depth-1"> <a href="#loopback-example-log-extension">@loopback/example-log-extension</a> </li> <li class="depth-2"> <a href="#overview">Overview</a> </li> <li class="depth-3"> <a href="#example-usage">Example Usage</a> </li> <li class="depth-2"> <a href="#cloning-the-example-project-locally">Cloning the example project locally</a> </li> <li class="depth-2"> <a href="#tutorial">Tutorial</a> </li> <li class="depth-3"> <a href="#src-keys-ts">/src/keys.ts</a> </li> <li class="depth-3"> <a href="#src-types-ts">src/types.ts</a> </li> <li class="depth-3"> <a href="#src-decorators-log-decorator-ts">src/decorators/log.decorator.ts</a> </li> <li class="depth-3"> <a href="#src-mixins-log-level-mixin-ts">src/mixins/log-level.mixin.ts</a> </li> <li class="depth-3"> <a href="#providers">Providers</a> </li> <li class="depth-3"> <a href="#src-providers-timer-provider-ts">src/providers/timer.provider.ts</a> </li> <li class="depth-3"> <a href="#src-providers-log-action-provider-ts">src/providers/log-action.provider.ts</a> </li> <li class="depth-3"> <a href="#src-index-ts">src/index.ts</a> </li> <li class="depth-3"> <a href="#src-component-ts">src/component.ts</a> </li> <li class="depth-2"> <a href="#testing">Testing</a> </li> <li class="depth-2"> <a href="#contributions">Contributions</a> </li> <li class="depth-2"> <a href="#tests">Tests</a> </li> <li class="depth-2"> <a href="#contributors">Contributors</a> </li> <li class="depth-2"> <a href="#license">License</a> </li> </ul> </div> <div class="col-lg-9 col-lg-offset-3 column" data-spy="scroll" data-target=".scroll-spy-target" data-offset="0"> <div class="readability"> <a name="change-log"></a><h1 id="undefinedchange-log">Change Log <small>v0.9.1</small></h1> <p>All notable changes to this project will be documented in this file. See <a href="https://conventionalcommits.org">Conventional Commits</a> for commit guidelines.</p> <p><a name="0.9.1"></a></p> <a name="0-9-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-9-0-loopback-example-log-extension-0-9-1-2018-05-08"></a><h2 id="undefined0-9-1-2018-05-08-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.9.0...@loopback/example-log-extension@0.9.1">0.9.1</a> (2018-05-08)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.9.0"></a></p> <a name="0-9-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-3-loopback-example-log-extension-0-9-0-2018-05-03"></a><h1 id="undefined0-9-0-2018-05-03-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.7.3...@loopback/example-log-extension@0.9.0">0.9.0</a> (2018-05-03)</h1> <a name="features"></a><h3 id="undefinedfeatures">Features</h3> <ul> <li>add helper package &quot;dist-util&quot; (<a href="https://github.com/strongloop/loopback-next/commit/532f153">532f153</a>)</li> </ul> <p><a name="0.8.0"></a></p> <a name="0-8-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-3-loopback-example-log-extension-0-8-0-2018-05-03"></a><h1 id="undefined0-8-0-2018-05-03-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.7.3...@loopback/example-log-extension@0.8.0">0.8.0</a> (2018-05-03)</h1> <a name="features-1"></a><h3 id="undefinedfeatures">Features</h3> <ul> <li>add helper package &quot;dist-util&quot; (<a href="https://github.com/strongloop/loopback-next/commit/532f153">532f153</a>)</li> </ul> <p><a name="0.7.3"></a></p> <a name="0-7-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-2-loopback-example-log-extension-0-7-3-2018-04-26"></a><h2 id="undefined0-7-3-2018-04-26-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.7.2...@loopback/example-log-extension@0.7.3">0.7.3</a> (2018-04-26)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.7.2"></a></p> <a name="0-7-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-1-loopback-example-log-extension-0-7-2-2018-04-26"></a><h2 id="undefined0-7-2-2018-04-26-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.7.1...@loopback/example-log-extension@0.7.2">0.7.2</a> (2018-04-26)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.7.1"></a></p> <a name="0-7-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-7-0-loopback-example-log-extension-0-7-1-2018-04-25"></a><h2 id="undefined0-7-1-2018-04-25-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.7.0...@loopback/example-log-extension@0.7.1">0.7.1</a> (2018-04-25)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.7.0"></a></p> <a name="0-7-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-3-loopback-example-log-extension-0-7-0-2018-04-16"></a><h1 id="undefined0-7-0-2018-04-16-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.6.3...@loopback/example-log-extension@0.7.0">0.7.0</a> (2018-04-16)</h1> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.6.3"></a></p> <a name="0-6-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-2-loopback-example-log-extension-0-6-3-2018-04-16"></a><h2 id="undefined0-6-3-2018-04-16-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.6.2...@loopback/example-log-extension@0.6.3">0.6.3</a> (2018-04-16)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.6.2"></a></p> <a name="0-6-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-1-loopback-example-log-extension-0-6-2-2018-04-12"></a><h2 id="undefined0-6-2-2018-04-12-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.6.1...@loopback/example-log-extension@0.6.2">0.6.2</a> (2018-04-12)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.6.1"></a></p> <a name="0-6-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-6-0-loopback-example-log-extension-0-6-1-2018-04-11"></a><h2 id="undefined0-6-1-2018-04-11-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.6.0...@loopback/example-log-extension@0.6.1">0.6.1</a> (2018-04-11)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.6.0"></a></p> <a name="0-6-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-2-loopback-example-log-extension-0-6-0-2018-04-11"></a><h1 id="undefined0-6-0-2018-04-11-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.5.2...@loopback/example-log-extension@0.6.0">0.6.0</a> (2018-04-11)</h1> <a name="bug-fixes"></a><h3 id="undefinedbug-fixes">Bug Fixes</h3> <ul> <li>change file names to fit advocated naming convention (<a href="https://github.com/strongloop/loopback-next/commit/0331df8">0331df8</a>)</li> </ul> <a name="features-2"></a><h3 id="undefinedfeatures">Features</h3> <ul> <li><strong>context:</strong> typed binding keys (<a href="https://github.com/strongloop/loopback-next/commit/685195c">685195c</a>)</li> </ul> <p><a name="0.5.3"></a></p> <a name="0-5-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-2-loopback-example-log-extension-0-5-3-2018-04-06"></a><h2 id="undefined0-5-3-2018-04-06-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.5.2...@loopback/example-log-extension@0.5.3">0.5.3</a> (2018-04-06)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.5.2"></a></p> <a name="0-5-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-1-loopback-example-log-extension-0-5-2-2018-04-04"></a><h2 id="undefined0-5-2-2018-04-04-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.5.1...@loopback/example-log-extension@0.5.2">0.5.2</a> (2018-04-04)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.5.1"></a></p> <a name="0-5-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-5-0-loopback-example-log-extension-0-5-1-2018-04-02"></a><h2 id="undefined0-5-1-2018-04-02-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.5.0...@loopback/example-log-extension@0.5.1">0.5.1</a> (2018-04-02)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.5.0"></a></p> <a name="0-5-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-4-1-loopback-example-log-extension-0-5-0-2018-03-29"></a><h1 id="undefined0-5-0-2018-03-29-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.4.1...@loopback/example-log-extension@0.5.0">0.5.0</a> (2018-03-29)</h1> <a name="code-refactoring"></a><h3 id="undefinedcode-refactoring">Code Refactoring</h3> <ul> <li>renamed example-getting-started to example-todo (<a href="https://github.com/strongloop/loopback-next/commit/7a09f1b">7a09f1b</a>)</li> </ul> <a name="breaking-changes"></a><h3 id="undefinedbreaking-changes">BREAKING CHANGES</h3> <ul> <li>example-getting-started is now example-todo</li> </ul> <p><a name="0.4.1"></a></p> <a name="0-4-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-4-0-loopback-example-log-extension-0-4-1-2018-03-23"></a><h2 id="undefined0-4-1-2018-03-23-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.4.0...@loopback/example-log-extension@0.4.1">0.4.1</a> (2018-03-23)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.4.0"></a></p> <a name="0-4-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-4-loopback-example-log-extension-0-4-0-2018-03-21"></a><h1 id="undefined0-4-0-2018-03-21-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.3.4...@loopback/example-log-extension@0.4.0">0.4.0</a> (2018-03-21)</h1> <a name="features-3"></a><h3 id="undefinedfeatures">Features</h3> <ul> <li><strong>rest:</strong> expose app.requestHandler function (<a href="https://github.com/strongloop/loopback-next/commit/20a41ac">20a41ac</a>)</li> </ul> <a name="breaking-changes-1"></a><h3 id="undefinedbreaking-changes">BREAKING CHANGES</h3> <ul> <li><strong>rest:</strong> <code>RestServer#handleHttp</code> was renamed to <code>RestServer#requestHandler</code>.</li> </ul> <p><a name="0.3.4"></a></p> <a name="0-3-4-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-3-loopback-example-log-extension-0-3-4-2018-03-14"></a><h2 id="undefined0-3-4-2018-03-14-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.3.3...@loopback/example-log-extension@0.3.4">0.3.4</a> (2018-03-14)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.3.3"></a></p> <a name="0-3-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-2-loopback-example-log-extension-0-3-3-2018-03-13"></a><h2 id="undefined0-3-3-2018-03-13-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.3.2...@loopback/example-log-extension@0.3.3">0.3.3</a> (2018-03-13)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.3.2"></a></p> <a name="0-3-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-1-loopback-example-log-extension-0-3-2-2018-03-08"></a><h2 id="undefined0-3-2-2018-03-08-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.3.1...@loopback/example-log-extension@0.3.2">0.3.2</a> (2018-03-08)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.3.1"></a></p> <a name="0-3-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-3-0-loopback-example-log-extension-0-3-1-2018-03-07"></a><h2 id="undefined0-3-1-2018-03-07-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.3.0...@loopback/example-log-extension@0.3.1">0.3.1</a> (2018-03-07)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.3.0"></a></p> <a name="0-3-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-2-0-loopback-example-log-extension-0-3-0-2018-03-06"></a><h1 id="undefined0-3-0-2018-03-06-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.2.0...@loopback/example-log-extension@0.3.0">0.3.0</a> (2018-03-06)</h1> <a name="features-4"></a><h3 id="undefinedfeatures">Features</h3> <ul> <li>upgrade from swagger 2 to openapi 3 (<a href="https://github.com/strongloop/loopback-next/commit/71e5af1">71e5af1</a>)</li> </ul> <p><a name="0.2.0"></a></p> <a name="0-2-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-1-2-loopback-example-log-extension-0-2-0-2018-03-01"></a><h1 id="undefined0-2-0-2018-03-01-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.1.2...@loopback/example-log-extension@0.2.0">0.2.0</a> (2018-03-01)</h1> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.1.2"></a></p> <a name="0-1-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-1-1-loopback-example-log-extension-0-1-2-2018-03-01"></a><h2 id="undefined0-1-2-2018-03-01-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.1.1...@loopback/example-log-extension@0.1.2">0.1.2</a> (2018-03-01)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.1.1"></a></p> <a name="0-1-1-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-0-1-0-loopback-example-log-extension-0-1-1-2018-02-23"></a><h2 id="undefined0-1-1-2018-02-23-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@0.1.0...@loopback/example-log-extension@0.1.1">0.1.1</a> (2018-02-23)</h2> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="0.1.0"></a></p> <a name="0-1-0-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-7-loopback-example-log-extension-0-1-0-2018-02-21"></a><h1 id="undefined0-1-0-2018-02-21-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@4.0.0-alpha.7...@loopback/example-log-extension@0.1.0">0.1.0</a> (2018-02-21)</h1> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="4.0.0-alpha.7"></a></p> <a name="4-0-0-alpha-7-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-6-loopback-example-log-extension-4-0-0-alpha-7-2018-02-15"></a><h1 id="undefined4-0-0-alpha-7-2018-02-15-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@4.0.0-alpha.6...@loopback/example-log-extension@4.0.0-alpha.7">4.0.0-alpha.7</a> (2018-02-15)</h1> <a name="bug-fixes-1"></a><h3 id="undefinedbug-fixes">Bug Fixes</h3> <ul> <li>clean up example-log-extension (<a href="https://github.com/strongloop/loopback-next/commit/f13f603">f13f603</a>)</li> </ul> <p><a name="4.0.0-alpha.6"></a></p> <a name="4-0-0-alpha-6-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-5-loopback-example-log-extension-4-0-0-alpha-6-2018-02-07"></a><h1 id="undefined4-0-0-alpha-6-2018-02-07-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@4.0.0-alpha.5...@loopback/example-log-extension@4.0.0-alpha.6">4.0.0-alpha.6</a> (2018-02-07)</h1> <a name="build"></a><h3 id="undefinedbuild">build</h3> <ul> <li>drop dist6 related targets (<a href="https://github.com/strongloop/loopback-next/issues/945">#945</a>) (<a href="https://github.com/strongloop/loopback-next/commit/a2368ce">a2368ce</a>)</li> </ul> <a name="breaking-changes-2"></a><h3 id="undefinedbreaking-changes">BREAKING CHANGES</h3> <ul> <li>Support for Node.js version lower than 8.0 has been dropped. Please upgrade to the latest Node.js 8.x LTS version.</li> </ul> <p>Co-Authored-by: Taranveer Virk <a href="mailto:taranveer@virk.cc">taranveer@virk.cc</a></p> <p><a name="4.0.0-alpha.5"></a></p> <a name="4-0-0-alpha-5-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-4-loopback-example-log-extension-4-0-0-alpha-5-2018-02-04"></a><h1 id="undefined4-0-0-alpha-5-2018-02-04-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@4.0.0-alpha.4...@loopback/example-log-extension@4.0.0-alpha.5">4.0.0-alpha.5</a> (2018-02-04)</h1> <a name="bug-fixes-2"></a><h3 id="undefinedbug-fixes">Bug Fixes</h3> <ul> <li>remove console output from tests (<a href="https://github.com/strongloop/loopback-next/commit/ff4a320">ff4a320</a>)</li> </ul> <p><a name="4.0.0-alpha.4"></a></p> <a name="4-0-0-alpha-4-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-3-loopback-example-log-extension-4-0-0-alpha-4-2018-01-30"></a><h1 id="undefined4-0-0-alpha-4-2018-01-30-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@4.0.0-alpha.3...@loopback/example-log-extension@4.0.0-alpha.4">4.0.0-alpha.4</a> (2018-01-30)</h1> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="4.0.0-alpha.3"></a></p> <a name="4-0-0-alpha-3-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-2-loopback-example-log-extension-4-0-0-alpha-3-2018-01-29"></a><h1 id="undefined4-0-0-alpha-3-2018-01-29-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@4.0.0-alpha.2...@loopback/example-log-extension@4.0.0-alpha.3">4.0.0-alpha.3</a> (2018-01-29)</h1> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="4.0.0-alpha.2"></a></p> <a name="4-0-0-alpha-2-https-github-com-strongloop-loopback-next-compare-loopback-example-log-extension-4-0-0-alpha-1-loopback-example-log-extension-4-0-0-alpha-2-2018-01-26"></a><h1 id="undefined4-0-0-alpha-2-2018-01-26-"><a href="https://github.com/strongloop/loopback-next/compare/@loopback/example-log-extension@4.0.0-alpha.1...@loopback/example-log-extension@4.0.0-alpha.2">4.0.0-alpha.2</a> (2018-01-26)</h1> <p><strong>Note:</strong> Version bump only for package @loopback/example-log-extension</p> <p><a name="4.0.0-alpha.1"></a></p> <a name="4-0-0-alpha-1-2018-01-26"></a><h1 id="undefined4-0-0-alpha-1-2018-01-26-">4.0.0-alpha.1 (2018-01-26)</h1> <a name="bug-fixes-3"></a><h3 id="undefinedbug-fixes">Bug Fixes</h3> <ul> <li>fix build config for example-log-extension (<a href="https://github.com/strongloop/loopback-next/commit/b48d85b">b48d85b</a>)</li> <li>make mocha self-contained with the source map support (<a href="https://github.com/strongloop/loopback-next/commit/7c6d869">7c6d869</a>)</li> <li>mark example-log-extension private to avoid npm publish (<a href="https://github.com/strongloop/loopback-next/commit/3ffbc64">3ffbc64</a>)</li> </ul> <a name="loopback-example-log-extension"></a><h1 id="undefined-loopback-example-log-extension">@loopback/example-log-extension</h1> <p>An example repo showing how to write a complex log extension for LoopBack 4</p> <a name="overview"></a><h2 id="undefinedoverview">Overview</h2> <p>This repository shows you how to use <a href="https://github.com/strongloop/loopback-next/tree/master/packages/cli">@loopback/cli</a> to write a complex logging extension that requires a <a href="http://loopback.io/doc/en/lb4/Using-components.html">Component</a>, <a href="http://loopback.io/doc/en/lb4/Decorators.html">Decorator</a>, and a <a href="http://loopback.io/doc/en/lb4/Mixin.html">Mixin</a>.</p> <p>To use this extension you can add the <code>LogMixin</code> to your Application which will provide you a function to set the Application wide log level as well as automatically load the <code>LogComponent</code>. Only Controller methods configured at or above the logLevel will be logged.</p> <p><em>You may alternatively load <code>LogComponent</code> yourself and set the log level using the appropriate binding keys manually if you don&#39;t wish to use the <code>LogMixin</code>.</em></p> <p>Possible levels are: DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; OFF</p> <p>_Possible levels are represented as numbers but users can use <code>LOG_LEVEL.${level}</code> to specify the value instead of using numbers._</p> <p>A decorator enables you to set the log level for Controller methods, at or above which it should be logged.</p> <a name="example-usage"></a><h3 id="undefinedexample-usage">Example Usage</h3> <pre><code class="lang-ts"><span class="hljs-keyword">import</span> {LogMixin, LOG_LEVEL, log} <span class="hljs-keyword">from</span> <span class="hljs-string">'loopback4-example-log-extension'</span>; <span class="hljs-comment">// Other imports ...</span> <span class="hljs-keyword">class</span> LogApp <span class="hljs-keyword">extends</span> LogMixin(BootMixin(RestApplication)) { <span class="hljs-keyword">constructor</span>(<span class="hljs-params">options?: ApplicationConfig</span>) { <span class="hljs-keyword">super</span>(options); <span class="hljs-keyword">this</span>.projectRoot = __dirname; <span class="hljs-keyword">this</span>.logLevel(LOG_LEVEL.ERROR); } } <span class="hljs-keyword">class</span> MyController { <span class="hljs-meta">@log</span>(LOG_LEVEL.WARN) <span class="hljs-meta">@get</span>(<span class="hljs-string">'/'</span>) hello() { <span class="hljs-keyword">return</span> <span class="hljs-string">'Hello LoopBack'</span>; } <span class="hljs-meta">@log</span>(LOG_LEVEL.ERROR) <span class="hljs-meta">@get</span>(<span class="hljs-string">'/name'</span>) helloName() { <span class="hljs-keyword">return</span> <span class="hljs-string">'Hello Name'</span>; } } </code></pre> <a name="cloning-the-example-project-locally"></a><h2 id="undefinedcloning-the-example-project-locally">Cloning the example project locally</h2> <p>You can obtain a local clone of this project (without the rest of our monorepo) using the following command:</p> <pre><code class="lang-sh">lb4 example todo </code></pre> <a name="tutorial"></a><h2 id="undefinedtutorial">Tutorial</h2> <p>Install <code>@loopback/cli</code> by running <code>npm i -g @loopback/cli</code>.</p> <p>Initialize your new extension project as follows: <code>lb4 extension</code></p> <ul> <li>Project name: <code>loopback4-example-log-extension</code></li> <li>Project description: <code>An example extension project for LoopBack 4</code></li> <li>Project root directory: <code>(loopback4-example-log-extension)</code></li> <li>Component class name: <code>LogComponent</code></li> <li>Select project build settings: <code>Enable tslint, Enable prettier, Enable mocha, Enable loopbackBuild</code></li> </ul> <p>Now you can write the extension as follows:</p> <a name="src-keys-ts"></a><h3 id="undefined-src-keys-ts"><code>/src/keys.ts</code></h3> <p>Define <code>Binding</code> keys here for the component as well as any constants for the user (for this extension that&#39;ll be the logLevel <code>enum</code>).</p> <pre><code class="lang-ts"><span class="hljs-comment">/** * Binding keys used by this component. */</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">namespace</span> EXAMPLE_LOG_BINDINGS { <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> APP_LOG_LEVEL = BindingKey.create&lt;LOG_LEVEL&gt;( <span class="hljs-string">'example.log.level'</span>, ); <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> TIMER = BindingKey.create&lt;TimerFn&gt;(<span class="hljs-string">'example.log.timer'</span>); <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> LOGGER = BindingKey.create&lt;LogWriterFn&gt;(<span class="hljs-string">'example.log.logger'</span>); <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> LOG_ACTION = BindingKey.create&lt;LogFn&gt;(<span class="hljs-string">'example.log.action'</span>); } <span class="hljs-comment">/** * Enum to define the supported log levels */</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">enum</span> LOG_LEVEL { DEBUG, INFO, WARN, ERROR, OFF, } </code></pre> <a name="src-types-ts"></a><h3 id="undefinedsrc-types-ts"><code>src/types.ts</code></h3> <p>Before we continue, we will need to install a new dependecy as follows:</p> <pre><code class="lang-shell">npm i @loopback/rest </code></pre> <p>Now we define TypeScript type definitions / interfaces for complex types and functions here.</p> <pre><code class="lang-ts"><span class="hljs-keyword">import</span> {ParsedRequest, OperationArgs} <span class="hljs-keyword">from</span> <span class="hljs-string">'@loopback/rest'</span>; <span class="hljs-comment">/** * A function to perform REST req/res logging action */</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> LogFn { ( req: ParsedRequest, args: OperationArgs, <span class="hljs-comment">// tslint:disable-next-line:no-any</span> result: <span class="hljs-built_in">any</span>, startTime?: HighResTime, ): <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">void</span>&gt;; startTimer(): HighResTime; } <span class="hljs-comment">/** * Log level metadata */</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> LevelMetadata = {level: <span class="hljs-built_in">number</span>}; <span class="hljs-comment">/** * High resolution time as [seconds, nanoseconds]. Used by process.hrtime(). */</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> HighResTime = [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>]; <span class="hljs-comment">// [seconds, nanoseconds]</span> <span class="hljs-comment">/** * Log writing function */</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> LogWriterFn = <span class="hljs-function">(<span class="hljs-params">msg: <span class="hljs-built_in">string</span>, level: <span class="hljs-built_in">number</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>; <span class="hljs-comment">/** * Timer function for logging */</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> TimerFn = <span class="hljs-function">(<span class="hljs-params">start?: HighResTime</span>) =&gt;</span> HighResTime; </code></pre> <a name="src-decorators-log-decorator-ts"></a><h3 id="undefinedsrc-decorators-log-decorator-ts"><code>src/decorators/log.decorator.ts</code></h3> <p>Extension developers can create decorators to provide &quot;hints&quot; (or metadata) to user artifacts such as controllers and their methods. These &quot;hints&quot; allow the extension to add extra processing accordingly.</p> <p>For this extension, the decorator marks which controller methods should be logged (and optionally at which level they should be logged). We leverage <code>@loopback/metadata</code> module to implement the decorator and inspection function.</p> <pre><code class="lang-ts"><span class="hljs-keyword">import</span> {LOG_LEVEL, EXAMPLE_LOG_BINDINGS} <span class="hljs-keyword">from</span> <span class="hljs-string">'../keys'</span>; <span class="hljs-keyword">import</span> { Constructor, MethodDecoratorFactory, MetadataInspector, } <span class="hljs-keyword">from</span> <span class="hljs-string">'@loopback/context'</span>; <span class="hljs-keyword">import</span> {LevelMetadata} <span class="hljs-keyword">from</span> <span class="hljs-string">'../types'</span>; <span class="hljs-comment">/** * Mark a controller method as requiring logging (input, output &amp; timing) * if it is set at or greater than Application LogLevel. * LOG_LEVEL.DEBUG &lt; LOG_LEVEL.INFO &lt; LOG_LEVEL.WARN &lt; LOG_LEVEL.ERROR &lt; LOG_LEVEL.OFF * * @param level The Log Level at or above it should log */</span> <span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">log</span>(<span class="hljs-params">level?: <span class="hljs-built_in">number</span></span>) </span>{ <span class="hljs-keyword">if</span> (level === <span class="hljs-literal">undefined</span>) level = LOG_LEVEL.WARN; <span class="hljs-keyword">return</span> MethodDecoratorFactory.createDecorator&lt;LevelMetadata&gt;( EXAMPLE_LOG_BINDINGS.METADATA, { level, }, ); } <span class="hljs-comment">/** * Fetch log level stored by `@log` decorator. * * @param controllerClass Target controller * @param methodName Target method */</span> <span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getLogMetadata</span>(<span class="hljs-params"> controllerClass: Constructor&lt;{}&gt;, methodName: <span class="hljs-built_in">string</span>, </span>): <span class="hljs-title">LevelMetadata</span> </span>{ <span class="hljs-keyword">return</span> ( MetadataInspector.getMethodMetadata&lt;LevelMetadata&gt;( EXAMPLE_LOG_BINDINGS.METADATA, controllerClass.prototype, methodName, ) || {level: LOG_LEVEL.OFF} ); } </code></pre> <a name="src-mixins-log-level-mixin-ts"></a><h3 id="undefinedsrc-mixins-log-level-mixin-ts"><code>src/mixins/log-level.mixin.ts</code></h3> <p>Extension users must set an app wide log level at or above which the decorated controller methods will be logged. A user can do so by binding the level to <code>example.log.level</code> but this can be a hassle.</p> <p>A mixin makes it easier for the user to set the application wide log level by providing it via <code>ApplicationOptions</code> or using a helper method <code>app.logLevel(level: number)</code>.</p> <pre><code class="lang-ts"><span class="hljs-keyword">import</span> {Constructor} <span class="hljs-keyword">from</span> <span class="hljs-string">'@loopback/context'</span>; <span class="hljs-keyword">import</span> {EXAMPLE_LOG_BINDINGS} <span class="hljs-keyword">from</span> <span class="hljs-string">'../keys'</span>; <span class="hljs-keyword">import</span> {LogComponent} <span class="hljs-keyword">from</span> <span class="hljs-string">'../component'</span>; <span class="hljs-comment">// tslint:disable-next-line:no-any</span> <span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">LogMixin</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">Constructor</span>&lt;<span class="hljs-title">any</span>&gt;&gt;(<span class="hljs-params">superClass: T</span>) </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">class</span> <span class="hljs-keyword">extends</span> superClass { <span class="hljs-comment">// tslint:disable-next-line:no-any</span> <span class="hljs-keyword">constructor</span>(<span class="hljs-params">...args: <span class="hljs-built_in">any</span>[]</span>) { <span class="hljs-keyword">super</span>(...args); <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options &amp;&amp; <span class="hljs-keyword">this</span>.options.logLevel) { <span class="hljs-keyword">this</span>.logLevel(<span class="hljs-keyword">this</span>.options.logLevel); } <span class="hljs-keyword">this</span>.component(LogComponent); } logLevel(level: LOG_LEVEL) { <span class="hljs-keyword">this</span>.bind(EXAMPLE_LOG_BINDINGS.APP_LOG_LEVEL).to(level); } }; } </code></pre> <a name="providers"></a><h3 id="undefinedproviders">Providers</h3> <p>A Providers is a class that returns a <code>value()</code> function that can be invoked by LoopBack 4.</p> <a name="src-providers-timer-provider-ts"></a><h3 id="undefinedsrc-providers-timer-provider-ts"><code>src/providers/timer.provider.ts</code></h3> <p>A timer than can be used to time the function that is being logged.</p> <pre><code class="lang-ts"><span class="hljs-keyword">import</span> {Provider} <span class="hljs-keyword">from</span> <span class="hljs-string">'@loopback/context'</span>; <span class="hljs-keyword">import</span> {TimerFn, HighResTime} <span class="hljs-keyword">from</span> <span class="hljs-string">'../types'</span>; <span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TimerProvider <span class="hljs-keyword">implements</span> Provider&lt;TimerFn&gt; { <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {} value(): TimerFn { <span class="hljs-keyword">return</span> (start?: HighResTime): <span class="hljs-function"><span class="hljs-params">HighResTime</span> =&gt;</span> { <span class="hljs-keyword">if</span> (!start) <span class="hljs-keyword">return</span> process.hrtime(); <span class="hljs-keyword">return</span> process.hrtime(start); }; } } </code></pre> <a name="src-providers-log-action-provider-ts"></a><h3 id="undefinedsrc-providers-log-action-provider-ts"><code>src/providers/log-action.provider.ts</code></h3> <p>This will be the most important provider for the extension as it is responsible for actually logging the request. The extension will retrieve the metadata stored by the <code>@log()</code> decorator using the controller and method name. Since bindings are resolved at runtime and these values change with each request, <code>inject.getter()</code> must be used to get a function capable of resolving the value when called. The action provider will look as follows:</p> <pre><code class="lang-ts">import {inject, Provider, Constructor, Getter} from '@loopback/context'; import {CoreBindings} from '@loopback/core'; import {OperationArgs, ParsedRequest} from '@loopback/rest'; import {getLogMetadata} from '../decorators/log.decorator'; import {EXAMPLE_LOG_BINDINGS, LOG_LEVEL} from '../keys'; import { LogFn, TimerFn, HighResTime, LevelMetadata, LogWriterFn, } from '../types'; import chalk from 'chalk'; export class LogActionProvider implements Provider&lt;LogFn&gt; { // LogWriteFn is an optional dependency and it falls back to `logToConsole` @inject(EXAMPLE_LOG_BINDINGS.LOGGER, {optional: true}) private logWriter: LogWriterFn = logToConsole; @inject(EXAMPLE_LOG_BINDINGS.APP_LOG_LEVEL, {optional: true}) private logLevel: number = LOG_LEVEL.WARN; constructor( @inject.getter(CoreBindings.CONTROLLER_CLASS) private readonly getController: Getter&lt;Constructor&lt;{}&gt;&gt;, @inject.getter(CoreBindings.CONTROLLER_METHOD_NAME) private readonly getMethod: Getter&lt;string&gt;, @inject(EXAMPLE_LOG_BINDINGS.TIMER) public timer: TimerFn, ) {} value(): LogFn { const fn = &lt;LogFn&gt;(( req: ParsedRequest, args: OperationArgs, // tslint:disable-next-line:no-any result: any, start?: HighResTime, ) =&gt; { return this.action(req, args, result, start); }); fn.startTimer = () =&gt; { return this.timer(); }; return fn; } private async action( req: ParsedRequest, args: OperationArgs, // tslint:disable-next-line:no-any result: any, start?: HighResTime, ): Promise&lt;void&gt; { const controllerClass = await this.getController(); const methodName: string = await this.getMethod(); const metadata: LevelMetadata = getLogMetadata(controllerClass, methodName); const level: number | undefined = metadata ? metadata.level : undefined; if ( level !== undefined &amp;&amp; this.logLevel !== LOG_LEVEL.OFF &amp;&amp; level &gt;= this.logLevel &amp;&amp; level !== LOG_LEVEL.OFF ) { if (!args) args = []; let msg = `${req.url} :: ${controllerClass.name}.`; msg += `${methodName}(${args.join(', ')}) =&gt; `; if (typeof result === 'object') msg += JSON.stringify(result); else msg += result; if (start) { const timeDiff: HighResTime = this.timer(start); const time: number = timeDiff[0] * 1000 + Math.round(timeDiff[1] * 1e-4) / 100; msg = `${time}ms: ${msg}`; } this.logWriter(msg, level); } } } function logToConsole(msg: string, level: number) { let output; switch (level) { case LOG_LEVEL.DEBUG: output = chalk.white(`DEBUG: ${msg}`); break; case LOG_LEVEL.INFO: output = chalk.green(`INFO: ${msg}`); break; case LOG_LEVEL.WARN: output = chalk.yellow(`WARN: ${msg}`); break; case LOG_LEVEL.ERROR: output = chalk.red(`ERROR: ${msg}`); break; } if (output) console.log(output); } </code></pre> <a name="src-index-ts"></a><h3 id="undefinedsrc-index-ts"><code>src/index.ts</code></h3> <p>Export all the files to ensure a user can import the necessary components.</p> <pre><code class="lang-ts"><span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">'./decorators/log.decorator'</span>; <span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">'./mixins/log-level.mixin'</span>; <span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">'./providers/log-action.provider'</span>; <span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">'./providers/timer.provider'</span>; <span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">'./component'</span>; <span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">'./types'</span>; <span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">'./keys'</span>; </code></pre> <a name="src-component-ts"></a><h3 id="undefinedsrc-component-ts"><code>src/component.ts</code></h3> <p>Package the providers in the component to their appropriate <code>Binding</code> keys so they are automatically bound when a user adds the component to their application.</p> <pre><code class="lang-ts"><span class="hljs-keyword">import</span> {Component, ProviderMap} <span class="hljs-keyword">from</span> <span class="hljs-string">'@loopback/core'</span>; <span class="hljs-keyword">import</span> {EXAMPLE_LOG_BINDINGS} <span class="hljs-keyword">from</span> <span class="hljs-string">'./keys'</span>; <span class="hljs-keyword">im