Git Product home page Git Product logo

logzio-log4j2-appender's Introduction

Logzio Log4j 2 Appender

Log4j 2 Appender that ships logs using HTTPS bulk

This appender sends logs to your Logz.io account, using non-blocking threading, bulks, and HTTPS encryption. Please note that this appender requires log4j version 2.7 and up, and java 8 and up.

Technical Information

This appender uses LogzioSender implementation. Once you send a log, it will be enqueued in the queue and 100% non-blocking. There is a background task that will handle the log shipment for you. This jar is an "Uber-Jar" that shades both LogzioSender, BigQueue, Gson and Guava to avoid "dependency hell".

Installation from maven

JDK 8:

    <dependency>
        <groupId>io.logz.log4j2</groupId>
        <artifactId>logzio-log4j2-appender</artifactId>
        <version>1.0.19</version>
    </dependency>

JDK 11 and above:

    <dependency>
        <groupId>io.logz.log4j2</groupId>
        <artifactId>logzio-log4j2-appender</artifactId>
        <version>2.0.1</version>
    </dependency>

The appender also requires a logger implementation, for example:

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.15.0</version>
    </dependency>

Log4 2 Example Configuration

    <Appenders>
        <LogzioAppender name="Logzio">
            <logzioToken>your-logzio-personal-token-from-settings</logzioToken>
            <logzioType>myAwesomeType</logzioType>
            <logzioUrl>https://listener.logz.io:8071</logzioUrl>
        </LogzioAppender>
       
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Logzio"/>
        </Root>
    </Loggers>

Parameters

Parameter Default Explained
logzioToken None Your Logz.io token, which can be found under "settings" in your account, If the value begins with $ then the appender looks for an environment variable or system property with the name specified. For example: $LOGZIO_TOKEN will look for environment variable named LOGZIO_TOKEN
logzioType java The log type for that appender, it must not contain any spaces
logzioUrl https://listener.logz.io:8071 The url that the appender sends to. If your account is in the EU you must use https://listener-eu.logz.io:8071
drainTimeoutSec 5 How often the appender should drain the queue (in seconds)
socketTimeoutMs 10 * 1000 The socket timeout during log shipment
connectTimeoutMs 10 * 1000 The connection timeout during log shipment
addHostname false Optional. If true, then a field named 'hostname' will be added holding the host name of the machine. If from some reason there's no defined hostname, this field won't be added
additionalFields None Optional. Allows to add additional fields to the JSON message sent. The format is "fieldName1=fieldValue1;fieldName2=fieldValue2". You can optionally inject an environment variable value using the following format: "fieldName1=fieldValue1;fieldName2=$ENV_VAR_NAME". In that case, the environment variable should be the only value. In case the environment variable can't be resolved, the field will be omitted.
debug false Print some debug messages to stdout to help to diagnose issues
compressRequests false Boolean. true if logs are compressed in gzip format before sending. false if logs are sent uncompressed.
exceedMaxSizeAction "cut" String. cut to truncate the message field or drop to drop log that exceed the allowed maximum size for logzio. If the log size exceeding the maximum size allowed after truncating the message field, the log will be dropped.

Parameters for in-memory queue

Parameter Default Explained
inMemoryQueueCapacityBytes 1024 * 1024 * 100 The amount of memory(bytes) we are allowed to use for the memory queue. If the value is -1 the sender will not limit the queue size.
inMemoryLogsCountCapacity -1 Number of logs we are allowed to have in the queue before dropping logs. If the value is -1 the sender will not limit the number of logs allowed.
inMemoryQueue false Set to true if the appender uses in memory queue. By default the appender uses disk queue

Parameters for disk queue

Parameter Default Explained
fileSystemFullPercentThreshold 98 The percent of used file system space at which the sender will stop queueing. When we will reach that percentage, the file system in which the queue is stored will drop all new logs until the percentage of used space drops below that threshold. Set to -1 to never stop processing new logs
gcPersistedQueueFilesIntervalSeconds 30 How often the disk queue should clean sent logs from disk
bufferDir(deprecated, use queueDir) System.getProperty("java.io.tmpdir") Where the appender should store the queue
queueDir System.getProperty("java.io.tmpdir") Where the appender should store the queue

Code Example

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class LogzioLog4j2Example {

    public static void main(String[] args) {
        Logger logger = LogManager.getLogger(LogzioLog4j2Example.class);
        
        logger.info("Testing logz.io!");
        logger.warn("Winter is coming");
    }
}

MDC

Each key value you will add to MDC will be added to each log line as long as the thread alive. No further configuration needed.

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;

public class LogzioLog4j2Example {

    public static void main(String[] args) {
        Logger logger = LogManager.getLogger(LogzioLog4j2Example.class);
        
        ThreadContext.put("Key", "Value");
        logger.info("This log will hold the MDC data as well");
    }
}

Will send a log to Logz.io that looks like this:

{
    "message": "This log will hold the MDC data as well",
    "Key": "Value",
    ... (all other fields you used to get)
}

Marker

Markers are named objects used to enrich log statements, so each log line will be enriched with its own. No further configuration needed.

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;

public class LogzioLog4j2Example {

    public static void main(String[] args) {
        Logger logger = LogManager.getLogger(LogzioLog4j2Example.class);
        Marker marker = MarkerManager.getMarker("Fatal");
        logger.error(marker, "This line has a fatal error");
    }
}

Will send a log to Logz.io that looks like this:

{
    "message": "This line has a fatal error",
    "Marker": "Fatal",
    ... (all other fields you used to get)
}

Release notes

  • 2.0.1
    • Updated LogzioSender version to 2.0.1
      • Add User-Agent header with logz.io information
  • 2.0.0 - THIS IS A SNAPSHOT RELEASE - SUPPORTED WITH JDK 11 AND ABOVE
    • Updated LogzioSender version to 2.0.0:
      • Fixes an issue where DiskQueue was not clearing disk space when using JDK 11 and above.
  • 1.0.19
    • Updated LogzioSender version to 1.1.8:
      • Fix an issue where log is not being truncated properly between size of 32.7k to 500k.
  • 1.0.18
    • updated logzio sender version, fixing IndexOutOfBounds exception with bigqueue
Expand to check old versions
  • 1.0.16
    • Added exceedMaxSizeAction parameter for handling oversized logs.
  • 1.0.15
    • Bump versions of log4j-core
  • 1.0.14
    • Bump versions of log4j-api and log4j-core
  • 1.0.13
    • Fix for issue #38, thanks to @idachev
    • Bump versions of log4j and guava
  • 1.0.11
    • add in memory queue option
    • change bufferDir(deprecated) to queueDir
  • 1.0.10
    • Allow to set type using environment variables.
  • 1.0.9
    • fix guava shaded dependency.
  • 1.0.8
    • added compressRequests parameter to enable gzip compression of the logs before they are sent.
    • added option to inject system property value into additionalFields, logzioUrl and token.
  • 1.0.6 - 1.0.7
  • 1.0.5
  • 1.0.3 - 1.0.4
    • add error message about reason of 400(BAD REQUEST)
  • 1.0.2
    • Fix problem where logzioToken and logzioUrl could not be environment variables
  • 1.0.1
  • 1.0.0
    • Initial releases

Contribution

  • Fork
  • Code
  • mvn test
  • Issue a PR :)

logzio-log4j2-appender's People

Contributors

8naama avatar abdel avatar asafm avatar bardabun avatar boofinka avatar guerremdq avatar idohalevi avatar karenjoseph avatar marinarazumovsky avatar mend-for-github-com[bot] avatar roiravhon avatar schwin007 avatar snyk-bot avatar talhibner avatar tamir-michaeli avatar yotamloe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

logzio-log4j2-appender's Issues

Logzio appender is stopped on Log4j2 reconfigure

I hit an issue that causes the Logzio appended to not work.

Immediate on spring boot start the Log4j2 is reconfigured - but the reconfiguration workflow is this:

  1. Start new Log4j2 configuration
  2. Start all new appenders
  3. Stop old Log4j2 configuration
  4. Stop all old appenders - here Logzio appended is shutdown forever

These are the logs:

Log4j2 config first starting appender:       ===> 2021-01-26 04:30:34,665 main INFO DEBUG: Created new LogzioSender class                                                                                                                                            
First logs send to Logzio                    ===> 2021-01-26 04:30:34,667 Log4j2-TF-2-LogzioAppender-1 INFO DEBUG: Attempting to drain queue                                                                                                                         
Log4j2 config second time starting appender: ===> 2021-01-26 04:30:35,288 main INFO Already found appender configured for type local, re-using the same one.                                                                                                         
Next logs send to Logzio                     ===> 2021-01-26 04:30:35,288 Log4j2-TF-2-LogzioAppender-3 INFO DEBUG: Attempting to drain queue                                                                                                                         
Log4j2 old config stoping appender:          ===> 2021-01-26 04:30:35,289 main INFO DEBUG: Got stop request, Submitting a final drain queue task to drain before shutdown. Will timeout in 20 seconds.                                                               
Last logs send to Logzio                     ===> 2021-01-26 04:30:35,290 pool-6-thread-1 INFO DEBUG: Attempting to drain queue 

unsafe memory access in AWS Lambda since 3 days

We get Unhandled Exceptions in our AWS Lambda functions for 3 days (2019-07-24). This exception occurs with version 1.0.7 and 1.0.11. We have not touched the Lambda function in the last months, so we suspect that AWS has changed something in its runtime environment. Unfortunately, with these changes, the library will no longer work.

Environment: we use java8 lambda environment.

a fault occurred in a recent unsafe memory access operation in compiled Java code: java.lang.InternalError
java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code
at java.nio.DirectByteBuffer.getLong(DirectByteBuffer.java:766)
at java.nio.DirectByteBuffer.getLong(DirectByteBuffer.java:772)
at io.logz.sender.com.bluejeans.common.bigqueue.BigArray.initArrayIndex(BigArray.java:243)
at io.logz.sender.com.bluejeans.common.bigqueue.BigArray.commonInit(BigArray.java:157)
at io.logz.sender.com.bluejeans.common.bigqueue.BigArray.<init>(BigArray.java:141)
at io.logz.sender.com.bluejeans.common.bigqueue.BigQueue.<init>(BigQueue.java:83)
at io.logz.sender.com.bluejeans.common.bigqueue.BigQueue.<init>(BigQueue.java:67)
at io.logz.sender.DiskQueue.<init>(DiskQueue.java:32)
at io.logz.sender.DiskQueue.<init>(DiskQueue.java:10)
at io.logz.sender.DiskQueue$Builder.build(DiskQueue.java:154)
at io.logz.sender.LogzioSender$Builder.getLogsQueue(LogzioSender.java:306)
at io.logz.sender.LogzioSender$Builder.build(LogzioSender.java:298)
at io.logz.log4j2.LogzioAppender.start(LogzioAppender.java:347)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:265)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:545)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:284)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:304)
at com.mercateo.image.processing.lambda.ImageProcessingLambda.<clinit>(ImageProcessingLambda.java:43)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)

log4j v1

Hi, where is v1 on github?

(v2 does not work in jars, known issue)

NullpointerException in Mule 3.9

When using the appender in the Mule 3.9 runtime, A NullpointException gets thrown on startup. Is it possible some dependencies are missing or I am overlooking something in the configuration?

As far as I am aware, Mule 3.9 uses Log4j2 (2.8.2) through SLF4J.

Stacktrace.txt
log4j2.xml

Exception after upgrade of log4j2 to 2.8.2

Root Cause: class java.lang.NoSuchMethodError
-- org.apache.logging.log4j.core.impl.ThrowableProxy.getCauseStackTraceAsString()Ljava/lang/String;
io.logz.log4j2.LogzioAppender.formatMessageAsJson(LogzioAppender.java:335)
io.logz.log4j2.LogzioAppender.append(LogzioAppender.java:309)
org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)

ClassNotFoundException: com.google.common.base.Splitter

Environment info:

logzip-log4j2 version: 1.0.9
java version: 1.8
AS: Wildfly 12
Docker image: jboss/wildfly:12.0.0.Final (CENTOS 7)
OS Host: Ubuntu 16.04

Appender config:

<LogzioAppender name="Logzio">
    <logzioToken>$LOGZIO_TOKEN</logzioToken>
    <logzioType>java</logzioType>
    <additionalFields>env=$ENV</additionalFields>
    <debug>true</debug>
    <logzioUrl>https://listener.logz.io:8071</logzioUrl>
</LogzioAppender>

Exception stacktrace:

wildfly    | Caused by: java.lang.NoClassDefFoundError: com/google/common/base/Splitter
wildfly    | 	at io.logz.log4j2.LogzioAppender.<init>(LogzioAppender.java:236)
wildfly    | 	at io.logz.log4j2.LogzioAppender.<init>(LogzioAppender.java:41)
wildfly    | 	at io.logz.log4j2.LogzioAppender$Builder.build(LogzioAppender.java:113)
wildfly    | 	at io.logz.log4j2.LogzioAppender$Builder.build(LogzioAppender.java:60)
wildfly    | 	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
wildfly    | 	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:952)
wildfly    | 	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:892)
wildfly    | 	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:884)
wildfly    | 	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:508)
wildfly    | 	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:232)
wildfly    | 	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:244)
wildfly    | 	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:545)
wildfly    | 	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
wildfly    | 	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
wildfly    | 	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
wildfly    | 	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
wildfly    | 	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
wildfly    | 	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
wildfly    | 	at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:551)
wildfly    | 	at ***********
wildfly    | 	at java.lang.Class.forName0(Native Method)
wildfly    | 	at java.lang.Class.forName(Class.java:348)
wildfly    | 	at org.jboss.invocation.proxy.AbstractProxyFactory.afterClassLoad(AbstractProxyFactory.java:91)
wildfly    | 	at org.jboss.invocation.proxy.AbstractClassFactory.defineClass(AbstractClassFactory.java:162)
wildfly    | 	at org.jboss.invocation.proxy.AbstractProxyFactory.getCachedMethods(AbstractProxyFactory.java:146)
wildfly    | 	at org.jboss.as.ejb3.component.stateless.StatelessComponentDescription$3.configure(StatelessComponentDescription.java:145)
wildfly    | 	at org.jboss.as.ee.component.DefaultComponentViewConfigurator.configure(DefaultComponentViewConfigurator.java:67)
wildfly    | 	at org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:92)
wildfly    | 	... 9 more

If I open de uber jar logzio-log4j2-appender-1.0.9.jar the shadded package /io/logz/sender/com/google/common/base/ doesn't contain the class Splitter.class (view attached image)

image

Logzio + spring boot

Hi all,
I am trying to use Logzion appender with Spring boot but I am getting this error:

java.lang.IllegalStateException: Logback configuration error detected: ERROR in ch.qos.logback.core.joran.spi.Interpreter@6:20 - no applicable action for [Appenders], current ElementPath is [[configuration][Appenders]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@7:43 - no applicable action for [LogzioAppender], current ElementPath is [[configuration][Appenders][LogzioAppender]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@8:30 - no applicable action for [logzioToken], current ElementPath is [[configuration][Appenders][LogzioAppender][logzioToken]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@9:29 - no applicable action for [logzioType], current ElementPath is [[configuration][Appenders][LogzioAppender][logzioType]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@10:28 - no applicable action for [logzioUrl], current ElementPath is [[configuration][Appenders][LogzioAppender][logzioUrl]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@14:18 - no applicable action for [Loggers], current ElementPath is [[configuration][Loggers]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@15:32 - no applicable action for [Root], current ElementPath is [[configuration][Loggers][Root]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@16:44 - no applicable action for [AppenderRef], current ElementPath is [[configuration][Loggers][Root][AppenderRef]]

My logback-spring.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>

<springProfile name="test">
    <Appenders>
        <LogzioAppender name="Logzio">
            <logzioToken>myToken</logzioToken>
            <logzioType>myAwesomeType</logzioType>
            <logzioUrl>https://listener.logz.io:8071</logzioUrl>
        </LogzioAppender>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Logzio"/>
        </Root>
    </Loggers>
</springProfile>

`

My pom.xml contains this dependencies related to logging:

   <dependency>
        <groupId>io.logz.log4j2</groupId>
        <artifactId>logzio-log4j2-appender</artifactId>
        <version>1.0.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>

Can you help me with this issue?

Thanks!

ERROR Uncaught error from Logz.io sender java.lang.IndexOutOfBoundsException: Index 214 is out of bounds [217 - 937]

Hi,
We're using logz.io appender for log4j2 to ship logs. While on x64 servers it's running fine, in the ARM instances we see next exception

2023-07-25 13:20:55,788 Log4j2-TF-1-LogzioAppender-1 ERROR Uncaught error from [Logz.io](http://logz.io/) sender java.lang.IndexOutOfBoundsException: Index 214 is out of bounds [217 - 937]
	at [io.logz.sender.org](http://io.logz.sender.org/).kairosdb.bigqueue.BigArrayImpl.validateIndex(BigArrayImpl.java:471)
	at [io.logz.sender.org](http://io.logz.sender.org/).kairosdb.bigqueue.BigArrayImpl.get(BigArrayImpl.java:411)
	at [io.logz.sender.org](http://io.logz.sender.org/).kairosdb.bigqueue.BigQueueImpl.dequeue(BigQueueImpl.java:124)
	at io.logz.sender.DiskQueue.dequeue(DiskQueue.java:65)
	at io.logz.sender.LogzioSender.dequeueUpToMaxBatchSize(LogzioSender.java:218)
	at io.logz.sender.LogzioSender.drainQueue(LogzioSender.java:234)
	at io.logz.sender.LogzioSender.drainQueueAndSend(LogzioSender.java:133)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:832)

Please advise , what can be an issue here ?
Thanks

Logs only get sent when stopping the application

Thank you for this appender. It happened though that the logs are getting sent by it only when the application is being stopped. My log4j configuration is the following:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="60">
    <Appenders>
        <Console name="Console-Appender" target="SYSTEM_OUT">
            <PatternLayout>
                <pattern>
                    [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
                </pattern>>
            </PatternLayout>
        </Console>

        <LogzioAppender name="Logzio">
            <logzioToken>[token]</logzioToken>
            <logzioType>java</logzioType>
            <logzioUrl>https://listener.logz.io:8071</logzioUrl>
            <addHostname>true</addHostname>
            <drainTimeoutSec>1</drainTimeoutSec>
            <debug>true</debug>
        </LogzioAppender>
    </Appenders>

    <Loggers>
        <Root level="info">
            <AppenderRef ref="Logzio"/>
            <AppenderRef ref="Console-Appender"/>
        </Root>
    </Loggers>
</Configuration>

I'd expect it to "drain and flush" every second but it doesn't. Literally sents all the logs only when I stop the application (CTRL+C). Any hint on why it could behave this way?

Note that the console appender works fine (i.e. it's displaying the logs on my console straight away.

LogzioAppender does not let the JVM exit

if I run the code example, it does not let the JVM exit (just sits there after the log statements). Probably the reason is of non-daemon thread.
Log4j 2 has a shutdownHook already specified, but since the JVM is not exiting (non-daemon thread), it is not getting called to shut down LogManager.

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.