Code Monkey home page Code Monkey logo

log4js-node's Issues

log messages can be logged out of time order

I have seen instances where log messages from different loggers are output in the wrong order:

[2011-10-20 12:02:20.694] [DEBUG] loggerone - log message 1
[2011-10-20 12:02:20.696] [DEBUG] loggertwo - log message 1
[2011-10-20 12:02:20.694] [DEBUG] loggerone - log message 2
[2011-10-20 12:02:20.697] [DEBUG] loggertwo - log message 2

Calling configure disables logging on all levels

Calling configure seems to disables logging of all messages. Take this example:

var log4js = require('log4js');

log4js.configure({
appenders: [
{ type: 'console', category:'tests' }
],
"levels": {
"tests": "INFO"
}
});
var log = log4js.getLogger('test');
log.warn('This message is not displayed.');

Change the readme to follow new examples

Now you have to define logger like this;

log4js.addAppender(log4js.consoleAppender());

Instead of the old (and less congruent)

log4js.addAppender(consoleAppender());

Thanks!

Log to stderr by default

It's more typical for console logs to go to stderr than stdout, to avoid interfering with "real" output from (for example) a command-line tool.

Disabling console replacement causes an exception?

Simple test case:

log4js = require ('log4js');

logger = log4js.getLogger();

logger.setLevel ('INFO');
log4js.restoreConsole();


logger.info("This line causes exception");

causes the following exception at the logger.info() line:

node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Object # has no method '_preLog4js_log'
at Logger. (/Users/nils/Documents/MobileSpan/Devel/git/bin/deploy/node_modules/log4js/lib/appenders/console.js:6:10)
at Logger.emit (events.js:67:17)
at Logger.log (/Users/nils/Documents/MobileSpan/Devel/git/bin/deploy/node_modules/log4js/lib/log4js.js:215:10)
at Logger.info (/Users/nils/Documents/MobileSpan/Devel/git/bin/deploy/node_modules/log4js/lib/log4js.js:233:38)
at Object. (/Users/nils/Documents/MobileSpan/Devel/git/bin/deploy/foo.js:10:8)
at Module._compile (module.js:432:26)
at Object..js (module.js:450:10)
at Module.load (module.js:351:31)
at Function._load (module.js:310:12)
at Array.0 (module.js:470:10)

Am I doing something wrong here?

Performance Analysis.

I did some tests to see how efficient the regex replace method is to format strings (https://github.com/nomiddlename/log4js-node/blob/master/lib/layouts.js#L31).

According to the tests I did simple string concatenation is much faster that regex replace method - around 3.5 times.

Here are the results:

stringAdd time: 36
stringAdd memory: { rss: 9277440, heapTotal: 3910080, heapUsed: 1682956 }

regex time: 117
regex memory: { rss: 9211904, heapTotal: 3926400, heapUsed: 1914876 }
var format = "%s %s some data string to: %s";
var a = "adfkjafgksjgfksjsgkjsf;gjsgfjs;fdg";
var b = "jadfjadfhjadfkjadfkjakdfjadkfjakdfjakfj";
var c = 5;

var NTIMES = 100000;

// use each test seperately - to test memory.

regexTest();
// arrayJoinTest();
// stringAddTest();

function regexTest() {
    var data = [a, b, c];
    var s = new Date();
    for (var i = 0; i < NTIMES; i++) {
        var k = 0;
        var str = format.replace(/%[sdj]/g, function (match) {
            switch (match) {
            case "%s": return new String(data[k++]);
            case "%d": return new Number(data[k++]);
            case "%j": return JSON.stringify(data[k++]);
            default:
                return match;
            }
        });
    }
    var e = new Date();
    console.log("regex time: %s", e - s);
    console.log("regex memory: %s", require("util").inspect(process.memoryUsage()));
}

function stringAddTest() {
    var data = [a, b, c];
    var s = new Date();
    for (var i = 0; i < NTIMES; i++) {
        f = format.split("%s");
        str = "";
        for (var j = 0, len = f.length - 1; j < len; j++) {
            str += f[j];
            str += data[j];
        }
        str += f[f.length - 1];
    }
    var e = new Date();
    console.log("stringAdd time: %s", e - s);
    console.log("stringAdd memory: %s", require("util").inspect(process.memoryUsage()));
}

function arrayJoinTest() {
    var data = [a, b, c];
    var s = new Date();
    var arr = [ ];
    for (var i = 0; i < NTIMES; i++) {
        f = format.split("%s");
        str = "";
        for (var j = 0, len = f.length - 1; j < len; j++) {
            arr.push(f[j]);
            arr.push(data[j]);
        }
        arr.push(f[f.length - 1]);
        arr.join("");
    }
    var e = new Date();
    console.log("arrayJoin time: %s", e - s);
    console.log("arrayJoin memory: %s", require("util").inspect(process.memoryUsage()));
}

logger.isLevelEnabled('debug') fail

I pass a string parameter to isLevelEnabled and it throw an exception:

[2011-12-27 13:55:14.197] [ERROR] app - Caught exception: TypeError: Object function Level(level, levelStr) { this.level = level; this.levelStr = levelStr; } has no method 'toLevel' at Level.isLessThanOrEqualTo (/home/chang/program/workspace/webgame-demo/node_modules/log4js/lib/levels.js:34:28) at Logger.isLevelEnabled (/home/chang/program/workspace/webgame-demo/node_modules/log4js/lib/log4js.js:219:23) I checkout the source code of levels.js and found that toLevel seems just a normal exported function but not a class method of class Level. So it fails when invoking inside the levels module.

If I pass logger.levels.DEBUG to isLevelEnabled, it will work well.

streams.js prints "DEBUG: current size =" to stderr on every log message

DEBUG: current size = 12107
DEBUG: current size = 12170
DEBUG: current size = 12321
DEBUG: current size = 12381
...
...

gets printed on every log message, when I configure a file appender with rolling logs. E.g: I used a JSON like below to pass to log4js.configure();

logAppenderJSON : {
"appenders": [
{
"type": "file",
"absolute": true,
"filename": "/tmp/my-server.log",
"maxLogSize": 100000,
"backups": 5,
"pollInterval" : 15,
"category": "my-server"
}
],
"levels": {
"fad-server": "TRACE"
}
}

why the log bak files are always changing?

I can't understand why u want the logfiles' fileName sort by the most updated index,like xxx.log.1,xxx.log.2.
when u do this:
1、the bak file's name will be updated again if a new file occured,it's waste of time
2、the fileName were always in updating so i can't get a copy of bak file which just the version i want! for example, i want the .log.4 but the file was always changing its content...

test script fails

Please list "vows" as a devDependency in your package.json so that the npat install will pick it up and the test can be run.

Can not install

Getting the following error when tried npm install log4js.

[email protected] install /Users/satheesh/Work/LearnNode/node_modules/log4js/node_modules/compress-buffer
make build

sh: make: command not found
npm ERR! error installing [email protected] Error: [email protected] install: make build
npm ERR! error installing [email protected] sh "-c" "make build" failed with 127
npm ERR! error installing [email protected] at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/exec.js:49:20)
npm ERR! error installing [email protected] at ChildProcess.emit (events.js:70:17)
npm ERR! error installing [email protected] at maybeExit (child_process.js:359:16)
npm ERR! error installing [email protected] at Process.onexit (child_process.js:395:5)
npm ERR! error installing [email protected] Error: [email protected] install: make build
npm ERR! error installing [email protected] sh "-c" "make build" failed with 127
npm ERR! error installing [email protected] at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/exec.js:49:20)
npm ERR! error installing [email protected] at ChildProcess.emit (events.js:70:17)
npm ERR! error installing [email protected] at maybeExit (child_process.js:359:16)
npm ERR! error installing [email protected] at Process.onexit (child_process.js:395:5)
npm ERR! error installing [email protected] Error: ENOENT, no such file or directory '/Users/satheesh/Work/LearnNode/node_modules/log4js/node_modules/___async.npm/package/.gitmodules'
npm ERR! [email protected] install: make build
npm ERR! sh "-c" "make build" failed with 127
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is most likely a problem with the compress-buffer package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! make build
npm ERR! You can get their info via:
npm ERR! npm owner ls compress-buffer
npm ERR! There is likely additional logging output above.
npm ERR!
npm ERR! System Darwin 11.2.0
npm ERR! command "node" "/usr/local/bin/npm" "install" "log4js"
npm ERR! cwd /Users/satheesh/Work/LearnNode
npm ERR! node -v v0.6.3
npm ERR! npm -v 1.1.0-alpha-2
npm ERR! code ELIFECYCLE
npm ERR! message [email protected] install: make build
npm ERR! message sh "-c" "make build" failed with 127
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /Users/satheesh/Work/LearnNode/npm-debug.log
npm not ok

When reloading is on and the file has not changed default configuration is loaded

File logtest.js:

var log4js = require('log4js');
var logger = log4js.getLogger('test');

log4js.configure('l4js.json', {reloadSecs: 3});

setInterval(function() { logger.info('Info test'); logger.debug('Debug test'); }, 1000);

File l4js.json:

{
"levels": {
        "test": "INFO"
}
}

Result:
[2011-08-29 05:45:35.039] [INFO] test - Info test
[2011-08-29 05:45:36.039] [INFO] test - Info test
[2011-08-29 05:45:37.039] [INFO] test - Info test
[2011-08-29 05:45:38.039] [INFO] test - Info test
[2011-08-29 05:45:39.039] [INFO] test - Info test
[2011-08-29 05:45:40.039] [INFO] test - Info test
[2011-08-29 05:45:40.040] [DEBUG] test - Debug test
[2011-08-29 05:45:41.039] [INFO] test - Info test
[2011-08-29 05:45:41.039] [DEBUG] test - Debug test
[2011-08-29 05:45:42.039] [INFO] test - Info test

rolling logs working?

I put a call in rollThatLog at the top to dump the logFile before "rolling":

[2011-07-21 18:50:21.560] [INFO] console - {"path":"/usr/local/hapa/logs/event_server/event_log.log","fd":6,"writable":true,"flags":"a","encoding":"utf8","mode":420,"busy":false,"_queue":[],"drainable":true}

Now after roll that log, notice the new log fd is null:

[2011-07-21 18:50:21.561] [INFO] console - {"path":"/usr/local/hapa/logs/event_server/event_log.log","fd":null,"writable":true,"flags":"a","encoding":"utf8","mode":420,"busy":true,"_queue":[]}

After this rotation, all subsequent logs still are going to the original log file, which is named .1 ....

0.4.2 not available

log4js 0.4.2 hasn't been published yet.
There is a fix in 0.4.2 which I need. Can you publish the new version to NPM?

Thanks,
Samet

console.log and multiple arguments

I just started using log4js-node. My projects use console.log and a lot of those calls have multiple arguments like

console.log(obj1, obj2, 'string');

log4js concats the arguments without spacers, console.log added spaces.

The behaviour should be that log4js adds spaces.

.log files doesn't have a new line end of each log item

i followed the example ,and with this 2 line code

logger.error('Cheese is too ripe!');
logger.fatal('Cheese was breeding ground for listeria.');

i have a .log file in my disk,but i found the 2 message are on one line,not have a new line on the second log item:

[the .log file:]
"
[2012-06-28 14:24:41.101] [ERROR] cheese - Cheese is too ripe![2012-06-28 14:24:41.108] [FATAL] cheese - Cheese was breeding ground for listeria.

"

Examples don't work

the examples provided do not work.

The only way to get a file appender is through JSON.

Enabling log rolling breaks with exception

I installed log4js:

ryppi install log4js

I've created my custom config:

log4js.json:

{
"appenders": [
{
"type": "console",
"layout": {
"type": "basic"
}
},
{
"type": "file",
"filename": "log_file.log",
"maxLogSize": 1024,
"backups": 3,
"pollInterval": 15
}
]
}

My node version:

node -v
v0.5.10

When I run application that does:

log4js.configure(__dirname + '/log4js.json', {
"reloadSecs": 10
});

It gives me:

Error: Problem reading log4js config ... . Error was "use fs.watch api instead".

In some earlier version of node was giving something about 'undefined is not a function' within fs.watchFile.

I run Node on Window 7 (both Cygwin built and windows binary give same error).

rolling file rename error

Found this error:
[2011-10-18 02:55:04.590] [ERROR] console - Error: ENOENT, No such file or directory '/foo/bar/node1/logs/foobar.log.9'
at Object.renameSync (fs.js:320:18)
at rollThatLog (/foo/bar/node_modules/log4js/lib/appenders/file.js:40:24)
at StatWatcher. (/foo/bar/node_modules/log4js/lib/appenders/file.js:29:21)

The interesting thing is that the error occured on foobar.log.4, but it's complaining about foobar.log.9, which exists btw, so I'm not sure why it's complaining about 'No such file or directory'.

The files at /foo/bar/node1/logs/:
-rw-r--r-- 1 octocat octocat 0 Oct 18 02:55 foobar.log
-rw-r--r-- 1 octocat octocat 0 Oct 18 02:55 foobar.log.1
-rw-r--r-- 1 octocat octocat 0 Oct 9 09:18 foobar.log.10
-rw-r--r-- 1 octocat octocat 0 Oct 18 02:55 foobar.log.2
-rw-r--r-- 1 octocat octocat 104858178 Oct 18 02:55 foobar.log.4
-rw-r--r-- 1 octocat octocat 121278872 Oct 17 12:47 foobar.log.5
-rw-r--r-- 1 octocat octocat 104858259 Oct 14 18:39 foobar.log.6
-rw-r--r-- 1 octocat octocat 403161013 Oct 14 12:15 foobar.log.8
-rw-r--r-- 1 octocat octocat 109284476 Oct 11 16:59 foobar.log.9

log4js.json:
{
"appenders": [{
"type": "logLevelFilter",
"level": "DEBUG",
"appender": {
"type": "file",
"filename": "/foo/bar/node1/logs/foobar.log",
"maxLogSize": 104857600,
"backups": 10,
"pollInterval": 15
}
}]
}

File logging stopped -no drain events - Node 0.6.1 - Windows 7

The file logger was stopping after about four messages.

Workaround was to bypass the queued logging.

Guess is that either Node or Windows is suppressing the drain events - the code as written implies that there will always be a drain event after a write, and after first open.

With more time, I'd have provided a replacement with a timer.

finding log4js.json

Hi,

I'm using etherpad-lite (https://github.com/Pita/etherpad-lite) which uses node.js and log4js-node. Due to some problem with socket code, I got a very large logfile and I realized that it was time to set up log rotation. I started to look into how this was done with log4js and I found that there is built-in logrolling, I just need to configure it.

Great. So since the application isn't configuring this anywhere, I followed the directions and created a log4js.json file with the following content straight from the example:

{
  "appenders": [
    {
      "type": "file",
      "filename": "/var/log/etherpad-lite/etherpad-lite.log",
      "maxLogSize": 1024,
      "backups": 3,
      "pollInterval": 15
    }
  ]
}

and then I puzzled over where I was supposed to put it. The documentation says the CWD is the first place looked, so I tried to figure out where exactly the CWD was. I decided the most logical place was the CWD of the node process, so I put it there (based on the value from /proc//cwd). It didn't seem to fire there. My current log file is larger than 1024 (by the way, what unit is that? bytes? megabytes?), so I expected it to rotate, but it didn't do anything. I plopped the log4js.json in various other locations that made less and less sense, including until I gave up.

Am I misunderstanding how this should work or is there a bug here?

thanks!

Feature: unittestAppender

Hi,

I thought to work on something that would look like this:

Synopsis

consider your unit-test to contain a test like this:

test("my operation emits logs properly", function(done) {

  var config = 
      { category: "my-operation"
      , maxEntries : 200   //keeps in memory maximum 200 entries per category 
      };

      testAppender = log4js.addAppender( log4js.unitestsAppender(config), "my-operation" ),
      myAutits = testAppender.getAudits();

  //this operation is assumed to send an entry to getLogger("my-operation")
  operationThatShouldEmitLogs(function(err, result){
      log4js.removeAppender( testAppender);

      assert.ok( 
        myAutits.contains(
          { level    : /INFO|WARN/
          , text     : /(Operation succeeded|Operation failed)/
          , category : "my-operation"
          }
        )
      );
});

or

var vows = require('vows')
   , claim = require('assert')
   ;

vows.describe(
   "my great utility"
).addBatch(
   { "my operation" :
     { topic: 
        function(){
           var cb = this.callback;
           var config = 
               { category: "my-operation"
               , maxEntries : 200   //keeps in memory maximum 200 entries per category 
               };

           testAppender = log4js.addAppender( log4js.unitestsAppender(config), "my-operation" ),
           myAutits = testAppender.getAudits();

           //this operation is assumed to send an entry to getLogger("my-operation")
           operationThatShouldEmitLogs( function(err,result) {
                  log4js.removeAppender( testAppender);
                  cb(err,result);
            });     
        }
     , "should emit loggs properly" :
        function(err, audit){
           assert.isUndefined(err);
           assert.isObject(audit);
           assert.ok( 
             myAutits.contains(
               { level    : /INFO|WARN/
               , text     : /(Operation succeeded|Operation failed)/
               , category : "my-operation"
               }
             )
           );
        }
     }
  }
);

API

I'm not final on the API design, and would love to talk about it with somebody
what I got now - and I'm not sure if its fully compatible with the underlying infra (log4js) is:

  • unitestsAppender
    -- implements Logger
    -- getAudits(0) - returns unitTestsAudits module
  • unitTestsAudits
    -- contains(query), where query can optionally specify level, text and category
    (why category? in case you audit few together)

Technicalities

I looked on ./lib/appenders/console - it looks quite easy to add an appender that will gather the entries in memory, so they can later be searched for assertions.
My real problems are -

  • technically how to do it with GIT and GITHUB...
  • I can't run the unit-tests - perhaps because I'm a windows user and the npm install fiddles with dependencies that are not cross-platform.

GITHUB

I'm still trying to take my first successful steps with github, with cloning a repo, working on a solution and sumbitting a pull request that is not editing a file on the github web editor...

Windows

I can offer help in making component cross-platform, the minuet we figure how to run it on windows, or how to ignore it if it's just wont...

I'd appreciate some help here... :)

Connect logging is broken

Running example-connect-logger.js from HEAD results in exception:

TypeError: Object #<Object> has no method 'isLevelEnabled'
    at Object.connectLogger (.../log4js/lib/connect-logger.js:47:17)
    at HTTPServer.<anonymous> (.../log4js/example-connect-logger.js:9:20)
    at HTTPServer.configure (.../express/lib/http.js:484:52)
    at Object.<anonymous> (.../log4js/example-connect-logger.js:8:5)
    at Module._compile (module.js:423:26)
    at Object..js (module.js:429:10)
    at Module.load (module.js:339:31)
    at Function._load (module.js:298:12)
    at Array.<anonymous> (module.js:442:10)
    at EventEmitter._tickCallback (node.js:175:26)

This is because require("connect-logger").getLogger() awaits a Logger instance as a first argument, but receives log4js module instance (with this).

When fixing this (for example, by removing "(this)" part in logj4s.js), it starts to work, but produces misformatted results like this:

[2011-07-18 20:08:14.445] [INFO] cheese - 1
'2''7''.''0''.''0''.''1'' ''-'' ''-'' ''"''G''E''T'' ''/'' ''H''T''T''P''/''1''.''1''"'' ''2''0''0'' ''1''1'' ''"''u''n''d''e''f''i''n''e''d''"'' ''"''l''w''p''-''r''e''q''u''e''s''t''/''5''.''8''3''4'' ''l''i''b''w''w''w''-''p''e''r''l''/''5''.''8''3''7''"'

This is due to calls like thislogger.log(level, format(fmt, req, res)), but Logger.prototype.log expecting an array. I.e. either thislogger.log should be called with [format(...)] array, or Logger.prototype.log (and level-named shortcuts) should be modified to accept variadic arguments.

SMTP appender

It would be great to have an SMTP appender so I can get alerts for fatals. Of course, that means endorsing a particular email library.

log4js still using require.paths

Which prevents it from running under node 0.5.x:

node.js:198
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: require.paths is removed. Use node_modules folders, or the NODE_PATH environment variable instead.
    at Function.<anonymous> (module.js:360:11)
    at findConfiguration (/Users/mark/work/foo/node_modules/log4js/lib/log4js.js:253:37)
    at Object.<anonymous> (/Users/mark/work/foo/node_modules/log4js/lib/log4js.js:387:11)
    at Module._compile (module.js:416:26)
    at Object..js (module.js:422:10)
    at Module.load (module.js:335:31)
    at Function._load (module.js:294:12)
    at Module.require (module.js:341:17)
    at require (module.js:352:17)
    at Object.<anonymous> (/Users/mark/work/foo/main.js:9:14)

can't seem to keep settings across multiple requires

So i have multiple files in my project. Let's say I have 2 files.

In one file I require log4js and then configure it using a file. Now, If I require log4js in another file, I lose all the configuration. This kinda breaks node's module system. I need to reconfigure it. However, as I do that I somehow lose my console configs. I like to output console to file as well and without colors but it always comes up with colors.

Any ideas? Thanks!!

Enabling configuartion reloading reloads the default configuration multiple times

So I have custom config file log4js-config.json

{
"appenders": [
{
"type": "console",
"layout": {
"type": "basic"
}
},
{
"type": "file",
"filename": "log/application_server.log"
}
]
}

This line:

log4js.configure(__dirname + '/log4js-config.json', {
"reloadSecs": 10
});

Will reload my config on any change but also each 10 seconds reload the default config (overwriting my settings - basic layout instead of colorized one (btw it doesn't work on Windows so you might consider some coloring library))

Set debug level per output

I would like to be able to define the level of logging on a per appender basis. Would it be possible to do something like:

var log4js = require('./log4js-node/lib/log4js-node');
log4js.addAppender(consoleAppender('INFO'));
log4js.addAppender(fileAppender('ERROR', 'logs/my.log'), 'my');
var logger = log4js.getLogger('my');

In my mind that would put all log messages below INFO and the log file would have all messages below ERROR. Is that possible now? Is that something that could be added?

Anyway to exclude some categories for an appender?

I have a lot categories, such as a, b, c, d, e... I want to configure the console appender to log all the categories but category c and e.
I check the source code and seems no exclude operation. I have to specify appender to log for category a, b, d, ... one by one to achieve it.
It would be better if I can exclude or specify categories for an appender by regular expression:)

How does one suppress consoleAppender?

I have a use case in which I would like log statements to go to a file, but use of console.log() to still go to the screen. For instance, when using nodeunit, I would like the results of each test to still echo to the screen, but all the minutiae of the tests to be logged to a file. Unfortunately, I'm unable to configure log4js such that these aren't commingled. I've tried clearAppenders() like so:

log4js.clearAppenders();
log4js.addAppender(log4js.fileAppender( '/my/fie.log'), 'main');

bu then I lose my nodeunit status messages entirely. How does one suppress consoleAppender?

It would be very usefull to process the loaded configuration on the topic of base path

Most of the time it would be convenient if you could control what relative paths in configuration file are resolved to. The most intuitive would be to resolve all the relative paths against the config file location. It could be easily done by adding something like basePath config property that is intialized to a loaded file name and than all the rest work with config requires to do path resolution against that path.

Feature Request

Roll the log over when the day changes... for example, at 12:00 AM, roll the log file :-)

Log file rolling can be slow due to lots of unnecessary fs.statSync calls

At each log file roll time, an fs.statSync call is made to check for the existence of each possible log file, based on the value of the "backups" config parameter in log4js.json. So, e.g., if "backups" is set to 100000, then 100K statSync calls are made, even if only a few log files actually exist. With high "backups" settings, this can cause a noticeable delay when log file rolling is triggered.

I think it would be better to check what files actually exist on the filesystem, via fs.readdirSync, for example, then do the rename operation on those.

appenders & use fs.watch instead (on node 0.5.10)

Hi, I am trying to use log4js on node 0.5.10. When I use a file appender with backup, it bails out with:

Error: Problem reading log4js config { appenders:
   [ { type: 'file',
       filename: 'node-consumer.log',
       maxLogSize: 1024,
       makers: [Object] } ] }. Error was "use fs.watch api instead" (Error: use fs.watch api instead
    at Object.watchFile (fs.js:696:11)

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.