Giter Site home page Giter Site logo

klogger's Introduction

KLogger: Simple Logging for PHP

A project written by Kenny Katzgrau and Dan Horrigan.

About

KLogger is an easy-to-use PSR-3 compliant logging class for PHP. It isn't naive about file permissions (which is expected). It was meant to be a class that you could quickly include into a project and have working right away.

If you need a logger that supports PHP < 5.3, see past releases for KLogger versions < 1.0.0.

Installation

Composer

From the Command Line:

composer require katzgrau/klogger:dev-master

In your composer.json:

{
    "require": {
        "katzgrau/klogger": "dev-master"
    }
}

Basic Usage

<?php

require 'vendor/autoload.php';

$users = [
    [
        'name' => 'Kenny Katzgrau',
        'username' => 'katzgrau',
    ],
    [
        'name' => 'Dan Horrigan',
        'username' => 'dhrrgn',
    ],
];

$logger = new Katzgrau\KLogger\Logger(__DIR__.'/logs');
$logger->info('Returned a million search results');
$logger->error('Oh dear.');
$logger->debug('Got these users from the Database.', $users);

Output

[2014-03-20 3:35:43.762437] [INFO] Returned a million search results
[2014-03-20 3:35:43.762578] [ERROR] Oh dear.
[2014-03-20 3:35:43.762795] [DEBUG] Got these users from the Database.
    0: array(
        'name' => 'Kenny Katzgrau',
        'username' => 'katzgrau',
    )
    1: array(
        'name' => 'Dan Horrigan',
        'username' => 'dhrrgn',
    )

PSR-3 Compliant

KLogger is PSR-3 compliant. This means it implements the Psr\Log\LoggerInterface.

See Here for the interface definition.

Setting the Log Level Threshold

You can use the Psr\Log\LogLevel constants to set Log Level Threshold, so that any messages below that level, will not be logged.

Default Level

The default level is DEBUG, which means everything will be logged.

Available Levels

<?php
use Psr\Log\LogLevel;

// These are in order of highest priority to lowest.
LogLevel::EMERGENCY;
LogLevel::ALERT;
LogLevel::CRITICAL;
LogLevel::ERROR;
LogLevel::WARNING;
LogLevel::NOTICE;
LogLevel::INFO;
LogLevel::DEBUG;

Example

<?php
// The 
$logger = new Katzgrau\KLogger\Logger('/var/log/', Psr\Log\LogLevel::WARNING);
$logger->error('Uh Oh!'); // Will be logged
$logger->info('Something Happened Here'); // Will be NOT logged

Additional Options

KLogger supports additional options via third parameter in the constructor:

<?php
// Example
$logger = new Katzgrau\KLogger\Logger('/var/log/', Psr\Log\LogLevel::WARNING, array (
    'extension' => 'log', // changes the log file extension
));

Here's the full list:

Option Default Description
dateFormat 'Y-m-d G:i:s.u' The format of the date in the start of the log lone (php formatted)
extension 'txt' The log file extension
filename [prefix][date].[extension] Set the filename for the log file. This overrides the prefix and extention options.
flushFrequency false (disabled) How many lines to flush the output buffer after
prefix 'log_' The log file prefix
logFormat false Format of log entries
appendContext true When false, don't append context to log entries

Log Formatting

The logFormat option lets you define what each line should look like and can contain parameters representing the date, message, etc.

When a string is provided, it will be parsed for variables wrapped in braces ({ and }) and replace them with the appropriate value:

Parameter Description
date Current date (uses dateFormat option)
level The PSR log level
level-padding The whitespace needed to make this log level line up visually with other log levels in the log file
priority Integer value for log level (see $logLevels)
message The message being logged
context JSON-encoded context

Tab-separated

Same as default format but separates parts with tabs rather than spaces:

$logFormat = "[{date}]\t[{level}]\t{message}";

Custom variables and static text

Inject custom content into log messages:

$logFormat = "[{date}] [$var] StaticText {message}";

JSON

To output pure JSON, set appendContext to false and provide something like the below as the value of the logFormat option:

$logFormat = json_encode([
    'datetime' => '{date}',
    'logLevel' => '{level}',
    'message'  => '{message}',
    'context'  => '{context}',
]);

The output will look like:

{"datetime":"2015-04-16 10:28:41.186728","logLevel":"INFO","message":"Message content","context":"{"1":"foo","2":"bar"}"}

Pretty Formatting with Level Padding

For the obsessive compulsive

$logFormat = "[{date}] [{level}]{level-padding} {message}";

... or ...

$logFormat = "[{date}] [{level}{level-padding}] {message}";

Why use KLogger?

Why not? Just drop it in and go. If it saves you time and does what you need, go for it! Take a line from the book of our C-code fathers: "build upon the work of others".

Who uses KLogger?

Klogger has been used in projects at:

* The University of Iowa
* The University of Laverne
* The New Jersey Institute of Technology
* Middlesex Hospital in NJ

Additionally, it's been used in numerous projects, both commercial and personal.

Special Thanks

Special thanks to all contributors:

License

The MIT License

Copyright (c) 2008-2015 Kenny Katzgrau [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

klogger's People

Contributors

chrisbjr avatar dhrrgn avatar drasive avatar jvalleroy avatar kamilwylegala avatar katzgrau avatar onno-vos-dev avatar onnovos avatar rbayliss avatar richjenks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

klogger's Issues

Invalid JSON

The method described in the README to get pure JSON appears to output invalid JSON.

This is the example output from the docs:

{"datetime":"2015-04-16 10:28:41.186728","logLevel":"INFO","message":"Message content","context":"{"1":"foo","2":"bar"}"}

It doesn't pass a JSON validator and causes json_decode() to return null.

This is valid JSON, without quotes around the context value:

{"datetime":"2015-04-16 10:28:41.186728","logLevel":"INFO","message":"Message content","context":{"1":"foo","2":"bar"}}

At the moment I'm just using Regex to remove the quotes.

Klogger creates empty file even if not used to log() anything

After playting with Slim (middleware and stuff) I noticed that when logger is created and even not used, a log file is created with zero size. Construct run setFileHandle() witch do fopen(...,'a') and this creates empty file, even if I don't log() anything (on PHP7 to be precise).

First I thought of moving setFileHandle() outside constructor or playing with different than 'a' file open modes, but then - why not use file_put_contents. It won't create file until it try to write to it, performance is (according to google) the same.

Do you see any drawbacks of it? Change was quite easy, code got cleaner. If you want, I can make a PR.

DateTime Fatal Error with PHP 5.6.11

I get this error when I try to use Klogger:
"
PHP Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in vendor/katzgrau/klogger/src/Logger.php:307
"

KLogger class initialization

Would probably be good to add the following to your KLogger.php file:

if (!class_exists('KLogger')) {
class KLogger
{
...
}
}

I only say this b/c otherwise you have to wrap every include / require with the check. Since this is a logging class, by it's definition it will likely be called / instantiated many times in page builds with errors / notices in them.

Just a thought. Thanks for all the work you've done on it regardless.

John

writing arrays

From the first example it appears arrays should be written to log. When I try to include an array, I get

PHP Notice: Array to string conversion in /data/Data_Cleaning/CvR/wip_plib/vendor/katzgrau/klogger/src/Logger.php on line 285

log shows

[2019-02-27 10:30:01.878930] [info] Array [2019-02-27 10:30:01.879091] [info] /data/Data_Cleaning/CvR/wip_pbin/file_cleaning/rename/NEX* [2019-02-27 10:30:01.879139] [info] Found: nex [2019-02-27 10:30:01.879228] [debug] Array [2019-02-27 10:30:01.879385] [info] NEX_IMR_01012019 renamed nex_wk01_01012019.txt [2019-02-27 10:30:01.879467] [info] NEX_IMR_01022019 renamed nex_wk01_01022019.txt [2019-02-27 10:30:01.879591] [info] NEX_IMR_01032019 renamed nex_wk01_01032019.txt [2019-02-27 10:30:01.879656] [info] NEX_IMR_01042019 renamed nex_wk01_01042019.txt [2019-02-27 10:30:01.879723] [info] NEX_IMR_01052019 renamed nex_wk01_01052019.txt [2019-02-27 10:30:01.879789] [info] NEX_IMR_01062019 renamed nex_wk01_01062019.txt [2019-02-27 10:30:01.879880] [info] NEX_IMR_01072019 renamed nex_wk01_01072019.txt [2019-02-27 10:30:01.879951] [info] NEX_IMR_01082019 renamed nex_wk02_01082019.txt [2019-02-27 10:30:01.880014] [info] NEX_IMR_01092019 renamed nex_wk02_01092019.txt

Am I missing something?

Dependency free / stand-alone version

It would be cool if there was a dependency free, one-file version of KLogger. It would be easier to integrate into projects that don't use composer.

Suggest to allow output to screen / stdout.

Setting the log dir to /dev/tty does not work, since you append the filename.
But changing it hardcoded in the file, to output to /dev/tty prints the log nicely to the screen.

Perhaps make a check for this condition and not try to append a filename and check for its exists status?

Option to tabulate log lines

I thought my log file would be more readable if all messages are indented with the same depth, no matter what $level. Example:

original

[2015-08-31 19:02:49.181617] [info] dumdidum
[2015-08-31 19:02:49.182616] [emergency] mist

nicer

[2015-08-31 19:03:27.268881] [info]      dumdidum
[2015-08-31 19:03:27.268881] [emergency] mist

So I changed line 553 (method formatMessage()) like this (original line is the commented one):

        //$message = "[{$this->getTimestamp()}] [{$level}] {$message}";
        $message = "[{$this->getTimestamp()}] [{$level}] ".str_repeat(' ',(9-strlen($level)))."{$message}";

Maybe it's helpful for someone.

Custom callback

Does anyone think the addition of custom callback feature would be of value? It could be passed the Logger object and/or Logger::lastLine and would open a lot of possibilities, for example:

  • Send an email if the level is notice or higher
  • Log emergency issues to a separate file
  • Mirror logs to a database
  • Delete/archive log files on a schedule

The developer would have to write the implementations themself (e.g. database connections) but custom callbacks might be a good way to allow advanced logging features without affecting how easy-to-use the basic functions are.

If people think this is of value I'll look into this feature.

Custom variable

Hi,

I don't understand how to use custom variable?

$logger = new Katzgrau\KLogger\Logger('C:/wamp/www/site/logs', Psr\Log\LogLevel::DEBUG, array(
    'extension' => 'log',
    'logFormat' => '[{date}] [{level}] [$myCustomVar] {message}'
));

and now where i can use it ?

$logger->info('my log');

Option for current log to be named differently than historical logs

It would be useful if the current day's logs could be written to a specifically titled file (such as current.log). As the date changes, that file should be renamed to the configured date format. This would make it far easier to monitor the current logs using external utilities.

Thoughts?

bug fix for instance()

Line 146 should read
if (in_array($logDirectory, array_keys(self::$instances)))

because if it doesn't every time the instance is called it will be recreated.

Set some Properties and Methods from private to protected

Hello Guys,

at first, thanks for this simple Class!
But I have some problems with it.

I would like to extend the Class for Read the file. But some Properties and Methods are on private, so I can not use it on my child class.

Example: $fileHandle & $logFilePath

Thanks. Greetz Sysix

can't stdout and log on file at same time

I'm using this:

    $GLOBALS['logger'] = new Katzgrau\KLogger\Logger(
        'php://stdout',
        Psr\Log\LogLevel::DEBUG, array(
            'extension' => 'log', // changes the log file extension
            'filename' => basename(__FILE__, '.php'),
            'logFormat' => "[{date}][{level}]\t{message}",
        )
    );

    $GLOBALS['logger']->setLogFilePath(__DIR__ . '/logs');

But for some reason, it's only logging on stdout and not saving on file
Any tip?

Bug - Args not printed on logDebug(msg, args)

Args are not printed on logDebug. This is because the $args variable was never passed in the logDebug() function.

$this->log($line, self::DEBUG);

should be

$this->log($line, self::DEBUG, $args);

Different log files in same class

What about having different log files? i.e. to have one file for database logs, another for payment services, another for core issues, and so on?

KLogger fails if log handle is not a resource

I've encountered an error that occurs when fopen() does not return a valid file handle. The KLogger class never checks if the file handle is a valid resource.

In method __construct():
if (($this->_fileHandle = fopen($this->_logFilePath, 'a'))) {

This just checks if there's something returned by fopen(), not if it's a valid resource handle.

Same here (__destruct()):
if ($this->_fileHandle) {
fclose($this->_fileHandle);
}

Error message:
Warning: fclose(): 62 is not a valid stream resource in /path/to/KLogger.php on line XX

There should be an additional is_resource() check in __construct() to fix this.

disable logging while leaving methods in place

Is there any way to turn off logging completely?
I want to turn it on/off depending on environment.

currently I'm handling it this way:

$this->log = new Katzgrau\KLogger\Logger(
    __DIR__.'/logs',
    (
        ( getenv('APP_ENV') == 'production' )
        ? Psr\Log\LogLevel::EMERGENCY
        : Psr\Log\LogLevel::DEBUG
    )
);

Split log file into smaller files

Hi guys just confirming Klogger doesn't have any functionality where it will automatically split large log files(say >5mb) into smaller log files eh?

If not that would be a good functionality to have.

Extension, filename and prefix not applying

Hello,

for some reason, the extension, filename and prefix settings do not apply.

$ composer clearcache
$ mkdir test
$ cd test
$ composer require katzgrau/klogger
$ touch index.php

In index.php:

<?php

require 'vendor/autoload.php';

$logger = new Katzgrau\KLogger\Logger(__DIR__, Psr\Log\LogLevel::DEBUG, array (
    'extension' => 'log'
));
$logger->error('error content');

It creates the log file, but in standard format log_2015-04-09.txt. Any explanation? Is it linked to my environment, so that I am the only one to have this issue?

If filename is provided, we should check if an extension is provided in the filename

Currently on Line 124 of Logger.php we check if the filename is provided. If so, we accept the filename as is without adding or checking for an extension.

if ($this->options['filename']) {
                $this->logFilePath = $logDirectory.DIRECTORY_SEPARATOR.$this->options['filename'];
            }

I suggest we do an additional check if the extension is provided as well. If not, the default logfile name should be chosen instead. This to prevent users from being able to add a filename and "expecting the default logextension" to be added to this but instead receive a filename without extension which could be problematic.

Class Logger not found

Hi guys,

I've just install KLogger via composer and I set the same options as in Basic Usage and I've got this error.
Fatal error: Class 'Katzgrau\KLogger\Logger' not found

If I try require just Logger.php from src. I've got an error:
Fatal error: Class 'Psr\Log\AbstractLogger' not found

[feature] optional JSON output

While the current format is certainly human-readable, and from the description and code KLogger certainly seems like a good tool, I think it could be helpful to add a toggle for JSON output. This would greatly aid users who want machine-readable logs, the main use-case I can think of would be a web dashboard with an area that lets you search and filter logs to for reading.

It could be a simple toggle between human- and machine-readable formats, or possible a setting to duplicate logging between the two.

Docs out of date

Hello

I noticed that some docs are out of date.

For example:
/**
* Class constructor
*
* @param string $logDirectory File path to the logging directory
* @param integer $logLevelThreshold The LogLevel Threshold
* @return void
*/
Return type is invalid.

/**
 * Sets the Log Level Threshold
 * 
 * @param string $dateFormat Valid format string for date()
 */

param name is incorrect.

/**
 * Writes a line to the log without prepending a status or timestamp
 *
 * @param string $line Line to write to the log
 * @return void
 */

param name is incorrect.

README "master" vs. "develop"

The file README.md features the third parameter of the constructor which is only available in the "develop"-branch but not in "master".

Warning: fwrite(): 38 is not a valid stream resource - only in lambda call

PHP Version 5.6.3

For my actual project i use a mix of klein.php for routing and KLogger for filelogging.

The logger is instanced in general in the app handler, and available in the routing classes which call "klein" routes inside:

<?php

namespace Router\Routes;

class GetHostInformations extends Base{

    public function init() {
        $that = $this;

        $this->getLogger()->debug('works');

        $this->getRouter()->getKlein()->respond('GET', '/hello-world', function (
                \Klein\Request $request, 
                \Klein\Response $response, 
                \Klein\ServiceProvider $service, 
                \Klein\App $app) use (&$that) {

            $that->getLogger()->debug('not working..'); // doesn work
            $this->getLogger()->debug('not working..'); // doesn work either

            return "hello-world";
        });
    }
}

If i request this route, all log files will be written, instead of the debug logs in the lambda function of klein.

Instead i get following error:

Warning: fwrite(): 38 is not a valid stream resource in C:\xampp\htdocs\project\application\vendor\katzgrau\klogger\src\Logger.php on line 227

Fatal error: Uncaught exception 'RuntimeException' with message 'The file could not be written to. Check that appropriate permissions have been set.' in C:\xampp\htdocs\project\application\vendor\katzgrau\klogger\src\Logger.php:228

If i check the filehandle in klogger vendor, i dont see any errors, i everytime get:

Resource id #38

But if i check the handle via stream_get_meta_data it returns false on the lambda call.

Why does the filehandle break on the lambda call?

Failed to open stream: File Exists?

Warning: fopen(C:\wamp64\www\xxxx\wp-temp\xxxx\logs\log_2018-05-14.txt): failed to open stream: File exists in C:\wamp64\www\xxxx\wp-content\plugins\xxxx\vendor\katzgrau\klogger\src\Logger.php on line 167

This is run through the earlier class and is attempting to open with an 'a' attribute.

"Fatal error: Class declarations may not be nested" when debugging with Netbeans

Hi there,

first I want to apologize if this not the right place to post this ... :-( I am using KLogger and PSR Log (https://github.com/php-fig/log) together with Symfony's ClassLoader Component (https://github.com/symfony/class-loader) to autoload KLogger and PSR Log.

My test code looks like this:

<?php

require_once __DIR__.'/class-loader/ClassLoader.php';

use Symfony\Component\ClassLoader\ClassLoader;

$loader = new ClassLoader();
$loader->register();

$loader->addPrefix('Psr\\Log', __DIR__);
$loader->addPrefix('Katzgrau\\KLogger', __DIR__);

$users = array(
    array(
        'name' => 'Kenny Katzgrau',
        'username' => 'katzgrau',
    ),
    array(
        'name' => 'Dan Horrigan',
        'username' => 'dhrrgn',
    )
);

$logger = new Katzgrau\KLogger\Logger(__DIR__.'/logs');
$logger->info('Returned a million search results');
$logger->error('Oh dear.');
$logger->debug('Got these users from the Database.', $users);

Everything works fine under this conditions:

  1. I do not debug
  2. I do debug (Netbeans, XDebug) and step into new Katzgrau\KLogger\Logger()

It does not work, if I set a breakpoint before new Katzgrau\KLogger\Logger() and when the breakpoint is reached I click "Continue (F5)". Then I get this fatal error:
Fatal error: Class declarations may not be nested in path\to\project\Psr\Log\LogLevel.php on line 9

I tried a lot to figure out what is going on. The only workaround I found was uncomment use Psr\Log\LogLevel; in Logger.php and copy the class definition of Psr\Log\Level directly into Logger.php (that's why I am posting it here).
But for obvious reasons I don't want to modify your code this way.

Does anyone know what and why is this happening?

Thanks a lot!

Regards

Support phpunit v6

For phpunit v6.0.0 and later, need to change PHPUnit_Framework_TestCase to PHPUnit\Framework\TestCase.

Specific Log Name in constructor

Wouldn't be useful to give the opportunity to choose the name file in the constructor?
Maybe this simple yet powerful log engine could be used more than one time in a project. Naming a log is something very important in some environments. And there is often a naming convention to follow.

New release for Packagist sourcing

Sorry to bug you again!

I am wondering if it would be possible to make a new release of KLogger so that I can pull the source down on Packagist, please. Right now, users trying to install our package get an error message because we've sourced KLogger on dev-master, and (as I had forgotten) our minimum-stability is too high for that.

pantheon-systems/terminus#622

Bad premissions for file after create

In class we can see

    /**
     * Octal notation for default permissions of the log file
     * @var integer
     */
    private $defaultPermissions = 0777;

But, it only set permissions for path, not for created log file.

Create and maintain a changelog

Just wanted to open an issue to open a discussion on whether or not we should have a basic change log.

I know we haven't bumped version for a while but we should consider having a more consistent version-bumping and change log in place.

@katzgrau @richjenks wdyt?

How to get version 1.0.0 using Composer

Hi,
I am unable to get version 1.0.0 using Composer. I always get v0.2.0, where the constructor didn't have the "$options" argument.

I tried "katzgrau/klogger": "1.0.*" and "katzgrau/klogger": "dev-master" but it doesn't seem to make a difference.

Does anybody have an idea what I could be doing wrong?

Parse logfile?

Hello,

Is there a way to parse the lines of a logfile given that, I know the format used to write these lines?

Thanks.

Packagist package is not correct

This may not be your problem at all but I just tried to use your package through Composer and the official Packagist site and it is not correct.

It seems a Github user named mediahack has cloned, but not forked the old klogger repo and submitted it to Packagist. The problem is, it's not going to update properly with Composer because it's a separate repo.

I don't know if Packagist has rules about this, but it comes up as katzgrau/KLogger as the name of the package despite it actually pointing to https://github.com/mediahack/klogger .

I noticed you have added Composer support in the 1.0.0 release. Have you submitted your own package to Packagist? They should probably remove the other one as they add yours.

Ability to change the logFormat on the fly

Just a simple method like public function setLogFormat($pFormat); to give the ability to change the format after the object creation.

public function setLogFormat($pFormat)
{
    $this->options["logFormat"] = $pFormat;
}

e.g. After the user has accepted the terms of use, the ip-address or the username could be added to the logformat without creating a new logger object.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.