logging.html 9.4 KB

1234567891011121314151617181920212223242526
  1. <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><title>Logging and Monitoring</title><link rel="stylesheet" href="./asciidoctor.css">
  2. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
  3. <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"><link rel="stylesheet" href="/home/travis/build/jMonkeyEngine/wiki/build/asciidoc/html5/jme3/advanced/twemoji-awesome.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/jme3/advanced/logging.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/jme3/advanced/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"></div><h1>Logging and Monitoring</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#logging-like-a-newbie">Logging Like a Newbie</a></li><li><a href="#logging-like-a-pro">Logging Like a Pro</a></li><li><a href="#switching-the-logger-on-and-off">Switching the Logger on and off</a></li><li><a href="#advanced-error-handling">Advanced Error Handling</a></li></ul></div></div><div id="content"><div class="sect1"><h2 id="logging-like-a-newbie">Logging Like a Newbie</h2><div class="sectionbody"><div class="paragraph"><p>Many developers just use <code>System.out.println()</code> to print diagnostic strings to the terminal. The problem with that is that before the release, you have to go through all your code and make certain you removed all these <code>println()</code> calls. You do not want your customers to see them, and needlessly worry about ominous outdated debugging diagnostics.</p></div></div></div>
  4. <div class="sect1"><h2 id="logging-like-a-pro">Logging Like a Pro</h2><div class="sectionbody"><div class="paragraph"><p>Instead of <code>println()</code>, use the standard Java logger from <code>java.util.logging</code>. It has many advantages for professional game development:</p></div>
  5. <div class="ulist"><ul><li><p>You tag each message with its <strong>log level</strong>: Severe error, informative warning, etc.</p></li><li><p>You can <strong>switch off or on printing of log messages</strong> up to certain log level with just one line of code.</p><div class="ulist"><ul><li><p>During development, you would set the log level to <code>fine</code>, because you want all warnings printed.</p></li><li><p>For the release, you set the log level to only report <code>severe</code> errors, and never print informative diagnostics.</p></li></ul></div></li><li><p>The logger message string is <strong>localizable</strong> and can use variables. Optimally, you localize all error messages.</p></li></ul></div>
  6. <div class="paragraph"><p>To print comments like a pro, you use the following logger syntax.</p></div>
  7. <div class="olist arabic"><ol class="arabic"><li><p>Declare the logger object once per file. In the following code, replace <code>HelloWorld</code> by the name of the class where you are using this line.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="predefined-type">Logger</span> LOGGER = <span class="predefined-type">Logger</span>.getLogger(HelloWorld.class.getName());</code></pre></div></div></li><li><p>Declare the info that you want to include in the message. The variables (here <code>a, b, c</code>) can be any printable Java object.<br>
  8. Example: <code>Vector3f a = cam.getLocation();</code></p></li><li><p>Put the variables in a new <code>Object</code> array. Refer to the variables as <code>{0},{1},{2}</code> etc in the message string. Variables are numbered in the order you put them into the <code>Object</code> array.</p></li><li><p>Add the logger line and specify the log level:</p><div class="ulist"><ul><li><p>Usecase 1: During debugging, a developer uses a warning to remind himself of a bug:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">LOGGER.log(<span class="predefined-type">Level</span>.WARNING, <span class="string"><span class="delimiter">&quot;</span><span class="content">why is {0} set to {1} again?!</span><span class="delimiter">&quot;</span></span>,
  9. <span class="keyword">new</span> <span class="predefined-type">Object</span><span class="type">[]</span>{a , b});</code></pre></div></div></li><li><p>Usecase 2: For the release, you inform the customer of a problem and how to solve it.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">LOGGER.log(<span class="predefined-type">Level</span>.SEVERE, <span class="string"><span class="delimiter">&quot;</span><span class="content">MyGame error: {0} must not be {1} after {2}! Adjust flux generator settings.</span><span class="delimiter">&quot;</span></span>,
  10. <span class="keyword">new</span> <span class="predefined-type">Object</span><span class="type">[]</span>{a , b , c});</code></pre></div></div></li></ul></div></li></ol></div>
  11. <div class="admonitionblock important"><table><tr><td class="icon"><i class="fa icon-important" title="Important"></i></td><td class="content"><div class="paragraph"><p>As you see in the examples, you should phrase potentially “customer facing errors in a neutral way and offer <em>a reason and a solution</em> for the error (if you don&#8217;t, it has no value to your customer). If your deveopment team uses WARNINGs as replacement for casual printlns, make sure you deactivate them for the release.</p></div></td></tr></table></div>
  12. <div class="paragraph"><p>More details about <a href="http://docs.oracle.com/javase/8/docs/api/java/util/logging/Level.html">Java log levels</a> here.</p></div></div></div>
  13. <div class="sect1"><h2 id="switching-the-logger-on-and-off">Switching the Logger on and off</h2><div class="sectionbody"><div class="paragraph"><p>In the release version you will deactivate the logging output to the terminal.</p></div>
  14. <div class="paragraph"><p>To deactivate the default logger for a release, you set the log level to only report <code>severe</code> messages:</p></div>
  15. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Logger</span>.getLogger(<span class="error">”</span><span class="error">”</span>).setLevel(<span class="predefined-type">Level</span>.SEVERE);</code></pre></div></div>
  16. <div class="paragraph"><p>During development or a beta test, you can tune down the default logger, and set the log level to only report <code>warning</code>s:</p></div>
  17. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Logger</span>.getLogger(<span class="error">”</span><span class="error">”</span>).setLevel(<span class="predefined-type">Level</span>.WARNING);</code></pre></div></div>
  18. <div class="paragraph"><p>To activate full logging, e.g. for debugging and testing, use the <code>fine</code> level:</p></div>
  19. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Logger</span>.getLogger(<span class="error">”</span><span class="error">”</span>).setLevel(<span class="predefined-type">Level</span>.FINE);</code></pre></div></div></div></div>
  20. <div class="sect1"><h2 id="advanced-error-handling">Advanced Error Handling</h2><div class="sectionbody"><div class="paragraph"><p>When an uncaught exception reaches certain parts of the jME3 system then the default response is to log the error and then exit the application. This is because an error happening every frame will rapidly fill logs with repeated failings and potentially mask or over-write the original cause of the problem or even the application may continue for a while and then suffer other errors caused by the first and make the root cause hard to determine.</p></div>
  21. <div class="paragraph"><p>This behaviour can be partially modified by overriding the method handleError in SimpleApplication, for example to display a custom message to users, or to provide users with information on how to report a bug or even to change the way that the error is logged.</p></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2019-12-20 23:30:51 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
  22. apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
  23. indexName: 'jmonkeyengine',
  24. inputSelector: '#doc-search',
  25. debug: false // Set debug to true if you want to inspect the dropdown
  26. });</script></body></html>