@loopback/docs
Version:
Documentation for LoopBack 4
823 lines (720 loc) • 52.2 kB
HTML
<!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 "dist-util" (<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 "dist-util" (<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't wish to use the <code>LogMixin</code>.</em></p>
<p>Possible levels are: DEBUG < INFO < WARN < ERROR < 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'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<LOG_LEVEL>(
<span class="hljs-string">'example.log.level'</span>,
);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> TIMER = BindingKey.create<TimerFn>(<span class="hljs-string">'example.log.timer'</span>);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> LOGGER = BindingKey.create<LogWriterFn>(<span class="hljs-string">'example.log.logger'</span>);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> LOG_ACTION = BindingKey.create<LogFn>(<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><<span class="hljs-built_in">void</span>>;
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>) =></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>) =></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 "hints" (or metadata) to
user artifacts such as controllers and their methods. These "hints" 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 & timing)
* if it is set at or greater than Application LogLevel.
* LOG_LEVEL.DEBUG < LOG_LEVEL.INFO < LOG_LEVEL.WARN < LOG_LEVEL.ERROR < 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<LevelMetadata>(
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<{}>,
methodName: <span class="hljs-built_in">string</span>,
</span>): <span class="hljs-title">LevelMetadata</span> </span>{
<span class="hljs-keyword">return</span> (
MetadataInspector.getMethodMetadata<LevelMetadata>(
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><<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">Constructor</span><<span class="hljs-title">any</span>>>(<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 && <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<TimerFn> {
<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> =></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<LogFn> {
// 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<Constructor<{}>>,
@inject.getter(CoreBindings.CONTROLLER_METHOD_NAME)
private readonly getMethod: Getter<string>,
@inject(EXAMPLE_LOG_BINDINGS.TIMER) public timer: TimerFn,
) {}
value(): LogFn {
const fn = <LogFn>((
req: ParsedRequest,
args: OperationArgs,
// tslint:disable-next-line:no-any
result: any,
start?: HighResTime,
) => {
return this.action(req, args, result, start);
});
fn.startTimer = () => {
return this.timer();
};
return fn;
}
private async action(
req: ParsedRequest,
args: OperationArgs,
// tslint:disable-next-line:no-any
result: any,
start?: HighResTime,
): Promise<void> {
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 &&
this.logLevel !== LOG_LEVEL.OFF &&
level >= this.logLevel &&
level !== LOG_LEVEL.OFF
) {
if (!args) args = [];
let msg = `${req.url} :: ${controllerClass.name}.`;
msg += `${methodName}(${args.join(', ')}) => `;
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