Code Monkey home page Code Monkey logo

mongodb_logger's Introduction

MongodbLogger

Build Status Code Climate

MongodbLogger is a alternative logger for Rails or Rack based app, which log all requests of you application into MongoDB database. It:

  • simple to integrate into existing Rails application;
  • allow to store all logs from web cluster into one scalable storage - MongoDB;
  • flexible schema of MongoDB allow to store and search any information from logs;
  • web panel allow filter logs, build graphs using MapReduce by information from logs;

Rails support

Please note the latest version is compatible with rails 3.1.x or newer.

For rails 3.0.x latest version 0.2.8.

Doesn't support the Rails version below 3.

Installation

  1. Add the following to your Gemfile then refresh your dependencies by executing "bundle install" (or just simple "bundle"):

     gem "mongodb_logger"
    
  2. Add adapter in Gemfile. Supported mongo and moped (mongoid). For example:

     gem "mongo"
     gem "bson_ext"
    

or

    gem "moped"
  1. Add the following line to your ApplicationController:

     include MongodbLogger::Base
    
  2. For use with Heroku you need to prevent the rails_log_stdout plugin from being added by Heroku for rails 3:

     mkdir vendor/plugins/rails_log_stdout
     touch vendor/plugins/rails_log_stdout/.gitkeep
    

    For Rails 4 just remove from Gemfile "rails_12factor" gem.

  3. Add MongodbLogger settings to database.yml for each environment in which you want to use the MongodbLogger. The MongodbLogger will also look for a separate mongodb_logger.yml or mongoid.yml (if you are using mongoid) before looking in database.yml. In the mongodb_logger.yml and mongoid.yml case, the settings should be defined without the 'mongodb_logger' subkey.

    database.yml:

     development:
       adapter: postgresql
       database: my_app_development
       username: postgres
       mongodb_logger:
         database: my_app               # required (the only required setting)
         capped: true                   # default: true  - warning: uncapped collections introduce the vulnerability that the size of the collection grows too high, exceeding all avaialble disk space
         capsize: <%= 10.megabytes %>   # default: 250MB - ignored if capped is set to false
         host: localhost                # default: localhost
         port: 27017                    # default: 27017
         username: null                 # default: null, username for MongoDB Auth
         password: null                 # default: null, password for MongoDB Auth
         replica_set: true              # default: false - Adds retries for ConnectionFailure during voting for replica set master
         write_options:                 # default: {w: 0, wtimeout: 200} - write options for inserts (w - wait for insert to propagate to "w" numbers of nodes)
           w: 0
           wtimeout: 200
         application_name: my_app       # default: Rails.application
         disable_file_logging: false    # default: false - disable logging into filesystem (only in MongoDB)
         collection: some_name          # default: Rails.env + "_log" - name of MongoDB collection
    

    mongodb_logger.yml:

     development:
       database: my_app
       capsize: <%= 10.megabytes %>
       host: localhost
       port: 27017
       replica_set: true
    

    Also you can use "url" parameter for setup connection to mongodb:

     development:
       url: mongodb://username:password@localhost:27017/my_app
       capsize: <%= 10.megabytes %>
    
  4. For using with MongoDB Replica Set (more info you can read by this link http://www.mongodb.org/display/DOCS/Replica+Sets). In config set list of [host, port] in key "hosts":

     development:
       database: my_app
       capsize: <%= 10.megabytes %>
       host: localhost
       port: 27017
       hosts:
         - - 127.0.0.1
           - 27018
         - - 127.0.0.1
           - 27019
    
  5. For assets pipeline you can generate all js/css file into folder by rake task:

     rake mongodb_logger:assets:compile[public/assets]
    

Assets pipeline

For capistrano possible compile assets by receipt. Add this to config/deploy.rb:

require 'mongodb_logger/capistrano'
set :mongodb_logger_assets_dir, "public/assets" # where to put mongodb assets
after 'deploy:update_code', 'mongodb_logger:precompile'

Also you can serve assets from rails app. You need just mount it separately:

mount MongodbLogger::Server.new, :at => "/mongodb", :as => :mongodb
mount MongodbLogger::Assets.instance, :at => "/mongodb/assets", :as => :mongodb_assets # assets

Usage

After success instalation of gem, a new MongoDB document (record) will be created for each request on your application, by default will record the following information: Runtime, IP Address, Request Time, Controller, Method, Action, Params, Application Name and All messages sent to the logger. The structure of the MongoDB document looks like this:

{
  'action'           : action_name,
  'application_name' : application_name (rails root),
  'controller'       : controller_name,
  'ip'               : ip_address,
  'messages'         : {
                         'info'  : [ ],
                         'debug' : [ ],
                         'error' : [ ],
                         'warn'  : [ ],
                         'fatal' : [ ]
                       },
  'params'           : { },
  'path'             : path,
  'request_time'     : date_of_request,
  'runtime'          : elapsed_execution_time_in_milliseconds,
  'url'              : full_url,
  'method'           : request method (GET, POST, OPTIONS),
  'session'          : information from session,
  'is_exception'     : true only for exceptions (in other cases this field miss)
}

Beyond that, if you want to add extra information to the base of the document (let's say something like user_id on every request that it's available), you can just call the Rails.logger.add_metadata method on your logger like so (for example from a before_filter):

# make sure we're using the MongodbLogger in this environment
Rails.logger.add_metadata(user_id: @current_user.id) if Rails.logger.respond_to?(:add_metadata)

Callback on exceptions

For send email or do something on exception you can add callback:

MongodbLogger::Base.configure do |config|
  config.on_log_exception do |mongo_record|
    # do something with this data, for example - send email (better - by background job)
  end
end

In this callback send record without "_id", because logger not wait for insert response from MongoDB.

Disable mongodb_logger

To disable MongodbLogger you can use option disable. But this should be set before rails load (for example in Rails app the top of "config/application.rb"):

MongodbLogger::Base.configure do |config|
  config.disable = true
end

or

 MongodbLogger::Base.disable = true

Migrate to another size of capped collection

If you need change capper collection size, you should change the "capsize" key in mongodb_config and run this task for migration:

rake mongodb_logger:migrate

Rack Middleware

If you want use MongodbLogger in Rack app which is mounted to your Rails app, you can try to use rack middleware:

use MongodbLogger::RackMiddleware

Rails::Engine

If you want use MongodbLogger with some of Rails::Engine, you can do this (example for Spree):

Spree::BaseController.send :include, MongodbLogger::Base
Spree::Admin::BaseController.send :include, MongodbLogger::Base # for admin

The Front End

To setup web interface in you Rails application, first of all create autoload file in you Rails application

File: you_rails_app/config/initializers/mongodb_logger.rb (example)

require 'mongodb_logger/server' # required
# this secure you web interface by basic auth, but you can skip this, if you no need this
MongodbLogger::Server.use Rack::Auth::Basic do |username, password|
    [username, password] == ['admin', 'password']
end

and just mount MongodbLogger::Server in rails routes:

File: you_rails_app/config/routes.rb

mount MongodbLogger::Server.new, :at => "/mongodb"

Now you can see web interface by url "http://localhost:3000/mongodb"

If you've installed MongodbLogger as a gem and want running the front end without Rails application, you can do it by this command:

mongodb_logger_web config.yml

where config.yml is config, similar to config of Rails apps, but without Rails.env. Example:

database: app_logs_dev
host: localhost
port: 27017
collection: development_log # set for see development logs

parameter "collection" should be set, if your set custom for your Rails application or start this front end not for production enviroment (by default taken "production_log" collection, in Rails application gem generate "#{Rails.env}_log" collection, if it is not defined in config).

It's a thin layer around rackup so it's configurable as well:

mongodb_logger_web config.yml -p 8282

Passenger, Unicorn, Thin, etc.

Using Passenger, Unicorn, Thin, etc? MongodbLogger ships with a config.ru you can use. See guide:

Don't forget setup MONGODBLOGGERCONFIG env variable, which provide information about MongodbLogger config. Example starting with unicorn:

MONGODBLOGGERCONFIG=examples/server_config.yml unicorn

Demo Application with MongodbLogger

Demo: http://demo-mongodb-logger.catware.org/

Demo Sources: https://github.com/le0pard/mongodb_logger_example_heroku

Querying via the Rails console

And now, for a couple quick examples on getting ahold of this log data... First, here's how to get a handle on the MongoDB from within a Rails console:

>> db = Rails.logger.mongo_adapter.connection
=> #<Mongo::DB:0x007fdc7c65adc8 @name="monkey_logs_dev" ... >
>> collection = Rails.logger.mongo_adapter.collection
=> #<Mongo::Collection:0x007fdc7a4d12b0 @name="development_log" .. >

Once you've got the collection, you can find all requests for a specific user (with id):

>> cursor = collection.find(:user_id => '12355')
=> #<Mongo::Cursor:0x1031a3e30 ... >
>> cursor.count
=> 5

Find all requests that took more that one second to complete:

>> collection.find({:runtime => {'$gt' => 1000}}).count
=> 3

Find all order#show requests with a particular order id (id=order_id):

>> collection.find({"controller" => "order", "action"=> "show", "params.id" => order_id})

Find all requests with an exception that contains "RoutingError" in the message or stack trace:

>> collection.find({"messages.error" => /RoutingError/})

Find all requests with errors:

>> collection.find({"is_exception" => true})

Find all requests with a request_date greater than '11/18/2010 22:59:52 GMT'

>> collection.find({:request_time => {'$gt' => Time.utc(2010, 11, 18, 22, 59, 52)}})

Using Uncapped Collections as Storage

MongoDB's capped collections are a safe choice for storing logs where expiration happens automatically after exceeding the provided capsize (first in first out expiration).

Capped collections comes with a few limitations, one of them being that you cannot manually delete log entries. Switching to a capped: false configuration will store all log entries in an uncapped collection and remove the constraints of uncapped collections.

Warning: If you choose to deploy mongodb_logger with an uncapped collection configuration, you should implement an alternative way of cleaning up log records (cron job or similar). Uncapped collections can grow indifinely in size and take up more disk space than you anticipated.

Copyright (c) 2009-2014 Phil Burrows, CustomInk (based on https://github.com/customink/central_logger) and Leopard released under the MIT license

mongodb_logger's People

Contributors

andreykozlov1984 avatar burgalon avatar buszu avatar derfred avatar dimonzozo avatar jonasnielsen avatar kelevro avatar le0pard avatar leonid-shevtsov avatar maxtor avatar nick-desteffen avatar oleriesenberg avatar slm-linus avatar smostovoy avatar tmgemedia avatar vltsu avatar waldher 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

mongodb_logger's Issues

Can't add metadata to logs!

I'm trying to add some very basic data to the logs in my application controller (i.e. for all actions). I've put this in place (confirmed that the method is running) but nothing is showing up in Mongo DB!

before_filter :add_metadata_to_mongolog

....

  private

  def add_metadata_to_mongolog

    # make sure we're using the MongodbLogger in this environment
    if Rails.logger.respond_to?(:add_metadata)
      if current_user
        id = current_user.id
        email = current_user.email
      else
        id = nil
        email = nil
      end

      Rails.logger.add_metadata(:additional_data => {:user_id => id, :user_email => email, :logged_in => !email.nil?})
    end
  end

Having trouble with setup on Heroku

The gem is working on my local machine. However, when I go to run it in Heroku with:

production:
  uri: <%= ENV['MONGOHQ_URL'] %>

staging:
  uri: <%= ENV['MONGOHQ_URL'] %>

I get the following:

Sorry there was a nasty error. Maybe no connection to MongoDB. Debug: #<NoMethodError: undefined method `find' for nil:NilClass><br />{"REMOTE_ADDR"=>"10.84.53.53", "REQUEST_METHOD"=>"GET", "REQUEST_PATH"=>"/app/admin/mongodb/overview", "PATH_INFO"=>"/overview", "REQUEST_URI"=>"/app/admin/mongodb/overview", "SERVER_PROTOCOL"=>"HTTP/1.1", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_X_FORWARDED_PROTO"=>"https", "HTTP_X_FORWARDED_PORT"=>"443", "HTTP_X_FORWARDED_FOR"=>"68.146.223.243", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.43 Safari/536.11"

.......

Do I have to have mongoid or mongo_mapper installed for this to work?

How to catch MOPED logs?

Hi! Is it possible to catch Moped logs?
I.e.:
MOPED: 127.0.0.1:27017 QUERY database=dating_development collection=users selector={"_id"=>"51d57961b3c480199"} flags=[] limit=0 skip=0 batch_size=nil fields={"last_action_at"=>1} (0.5791ms).
They are disappeared from stock logs and I've been expecting they would be shown at the mongodb_logger web interface. But there are no such messages. Could you please advice how to make them shown there?

Log messages (debug/info/warn etc.) don't show up

Hello,

I have mongodb_logger generally working, except that it isn't capturing log messages. I have the following in my code:

logger.warn "Warning about something!"

But it does not get captured in the "messges => warn" hash. I have looked in the front end log view, as well as in the database itself.

Nothing shows up in log/development.log, so mondodb_logger is definitely picking something up. If I use:

puts "Warning about something!"

it shows up in my logfile.

Production logs not created when mongodb_logger can't connect

Hi all

When I use mongodb_logger in production and for whatever reason it cannot connect to mongo, I fail to get anything logged to my production.log.

I'm running the latest gem.

The error i get is:

MongodbLogger Initializer Error: Unable to access log file. Please ensure that /[Rails Root]/log/production.log exists and is chmod 0666. The log level has been raised to WARN and the output directed to STDERR until the problem is fixed.
Expected response 1 but got 3289390.

The log file is totally writeable, I have even tired recreating it. I just don't get any output to it.

Any thoughts?

Thanks

Stuart

How to log message from Rails Console or Resque Jobs

I ran this command from console
Rails.logger.info "Test message from console"
but I cannot find that message on MongodbLogger, I only see that message was logged to log/development.log only

Is there any settings that enable log message to MongoDB from console?

Mongoid 5.1 support

Is anyone having issues with Mongoid 5.1?

Here is my setup. Rails 4.2.5.1 / Mongoid 5.1.1 / Mongo 2.4.14 / mongodb_logger 0.6.5. I see the development_log collection in my mongo DB but I get these errors trying to run rake mongodb_logger:* tasks.

MongodbLogger WARNING: Using Rails Logger due to exception: uninitialized constant Mongo::MongoClient

Also nothing actually gets logged into development_log collection.

Here is my config/mongodb_logger.yml
development:
database: rails425_dev
capsize: <%= 10.megabytes %>
host: localhost
port: 27017
replica_set: false

NoMethodError at /mongodblogs/overview undefined method `merge!' for "index":String

Messages node is empty

Added mongodb_logger to existing application based on Rails 3.2.6. Everything seems working fine but messages node is empty for each logged messaged. Do you have any ideas, why it could happen?

Thanks.

using mongodb_logger in any applications with one web interface

How about using mongodb_logger in any applications?

If I have any applications and want using standalone application with mongodb_logger to view logs.

Example:
app_1 (only logger)
app_2 (only logger)
app_3 (only logger)

MongoDBLogger:
app_4 (only web interface with switch between applications)

Routing Errors not appearing in the logs

I am using version 0.4.2 in development and when I get a routing error in my application I see that no log entry is added to the mongodb database. Is this expected?

You do not use capped collection for logs

I keep getting the message "You do not use capped collection for logs" on the mongodb webpage, but mongo says my collections are capped:

$ mongo
MongoDB shell version: 2.2.0
connecting to: test

use jigsaw
switched to db jigsaw
db.production_log.isCapped()
true

I am using 0.3.2

Mongodb logger exception on server

I have mongodb logger working locally, but when I run it on my server I am getting an exception.

Sorry there was a nasty error. Maybe no connection to MongoDB. Debug: NoMethodError: undefined method `filter_by_conditions' for nil:NilClass>
{"SERVER_SOFTWARE"=>"Apache/2.2.22 (Ubuntu)", "SERVER_PROTOCOL"=>"HTTP/1.1"

My mongodb_logger.yml
development:
database: my_app_logs
capsize: <%= 1000.megabytes %>
host: localhost
port: 27017
replica_set: true

production:
database: my_app_prod_logs
capsize: <%= 1000.megabytes %>
host: localhost
port: 27017
replica_set: true

On my server I am running in production mode. I tried the rake task to precompile the assets, that ran successfully. Also have the capistrano task found in the readme in my deploy.rb. Any hints on how to debug/fix this? I'm using mongodb_logger (0.4.1)

superclass mismatch for class Binary when used with Mongoid 3.0 rc

This has been happening pre RC for Mongoid 3, but now that the RC is out I wanted to bring it up.

If I remove mongodb_logger from my app the error goes away. This gets thrown anytime the app is loaded/run.

Thoughts?

/Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.2/lib/bson/types/binary.rb:27:in <module:BSON>': superclass mismatch for class Binary (TypeError) from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.2/lib/bson/types/binary.rb:21:in<top (required)>'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:in require' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:inblock in require'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:236:in load_dependency' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:inrequire'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.2/lib/bson.rb:70:in <top (required)>' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:inrequire'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:in block in require' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:236:inload_dependency'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:in require' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.2/lib/mongo.rb:53:in<top (required)>'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:in require' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:inblock in require'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:236:in load_dependency' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:inrequire'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/mongodb_logger-0.2.8/lib/mongodb_logger.rb:3:in <top (required)>' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.1.4/lib/bundler/runtime.rb:68:inrequire'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.1.4/lib/bundler/runtime.rb:68:in block (2 levels) in require' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.1.4/lib/bundler/runtime.rb:66:ineach'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.1.4/lib/bundler/runtime.rb:66:in block in require' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.1.4/lib/bundler/runtime.rb:55:ineach'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.1.4/lib/bundler/runtime.rb:55:in require' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.1.4/lib/bundler.rb:119:inrequire'
from /Users/ghent/Code/Rails/lookingglass/config/application.rb:13:in <top (required)>' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.3/lib/rails/commands.rb:53:inrequire'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.3/lib/rails/commands.rb:53:in block in <top (required)>' from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.3/lib/rails/commands.rb:50:intap'
from /Users/ghent/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.3/lib/rails/commands.rb:50:in <top (required)>' from script/rails:6:inrequire'
from script/rails:6:in `

'

assets are not loaded in staging and production

Although the gem works fine in development, the web interface in staging and production is rendered without the assets. Do I need to add the path to the asset precompile path? or should that be done automatically?

Filter what to log to MongoDB

Is it possible to filter what gets logged to MongoDB? I would like to only log messages with severity ERROR (exceptions).

Or only requests to specific routes. Or log different types of messages to different collections which can have different capped sizes / TTL indexes. This way I can keep certain types of messages longer than others.

Not working with moped 2.0 beta/beta2

Hi,
Once I update my project to moped 2.0 beta or beta2, no logs from mongodb_logger are recorded on my database, the collection I specified on my mongoid.yml for logger is created, but stays empty. No error messages.
As soon as I have a little more time, I'll try to investigate further.
Thanks
Jorge.

Consider reducing # of Rails versions you are running CI against

I see that mongodb_logger is being tested against every Rails 3.0.x and 3.1.x version ever released. While it is a nice idea to test against multiple versions, this means mongodb_logger takes 14-15 minutes for each build on travis-ci.org. Please consider only testing against 2 most recent 3.0.x and 3.1.x (and, eventually, 3.2.x) releases. You can still run tests against every Rails version out there locally, you can detect travis using ENV["CI"] being set.Thank you.

Rails 5 support

As far as I can tell mongodb_logger should be able to support Rails 5 once Sinatra is Rails 5 compatible (issue here).

Meanwhile anyone coming across this can use:

# Gemfile
gem 'rack-protection', github: 'sinatra/rack-protection'
gem 'sinatra', github: 'sinatra/sinatra'
gem 'mongodb_logger',
  github: 'JonasNielsen/mongodb_logger',
  branch: 'rails-5'

That's necessary because sinatra is disabled in .gemspec

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.