amonapp / amonagent Goto Github PK
View Code? Open in Web Editor NEWSingle binary agent for Linux
Home Page: https://amon.cx
License: MIT License
Single binary agent for Linux
Home Page: https://amon.cx
License: MIT License
Have you considered allowing users to set tags either via /etc/opt/amonagent/amonagent.conf
file or a seperate tags file? Kind of like subscriptions for sensu, though not for the same purpose. This would make deployments of amonagent much more configurable.
Alternatively, or additionally, it may also be a good idea to dynamically generate "reserved" tags based off of system information on behalf of the user at install time. Same thought as grains for saltstack, or facts for puppet. Things like os, distro, etc.
I believe this might be similar the issue/request brought up on #9.
We have 2 servers that randomly stop sending data (ironically I restart them around the same time and they seem to stop sending data around the same time). When I check the amonagent.log I can see that no new entries are logged starting around the time they stop sending data.
I am still in the process of trying to debug/troubleshoot what might be causing this. None of our other servers have this issue, which is leading me to think that a) some other process on these servers are interrupting amonagent or b) something about how these servers are configured (at the OS level) is causing the problem.
Some facts:
I am going to try updating them to the latest amonagent today to see if that helps resolve the issue.
I will gladly update this issue with any additional findings or potential patches if I am able to track this down.
Datadog recently separated their individual checks into separate packages, which will work great with the amonagent:
It would be fantastic to have a Raspberry Pi compatible build of the amon agent. The armhf
build sadly doesn't work.
Arch of Raspberry PI 3: armv7l
Currently amonagent seems to log to stderr using the default configuration of https://github.com/sirupsen/logrus/. When run as a systemd service this results in the logs going to syslog.
Our desire is to be able to log to a separate file instead of to syslog in order to be able to set a custom logrotate config for it.
It makes sense that the would be a on optional configuration in amon.conf that allows you to define where the log file would be stored.
http://packages.amon.cx/repo/ returns NoSuchKey
It's also only reachable on legacy IP, so newer nodes that are v6-only may not be able to reach it, but that's probably a separate issue.
When running as a user without appropriate permissions to write / access that path the following happens:
$ runuser -l eliezerlp -c 'amonagent -debug'
open /etc/opt/amonagent/machine-id: permission deniedinvalid argumentINFO[0000] Starting Amon Agent (Version: 0.7-1-g6f1eeeb)
INFO[0000] Agent Config: Interval:1m0s
open /etc/opt/amonagent/machine-id: permission deniedinvalid argumentINFO[0003] Metrics collected (Interval:1m0s)
{
"system": {
"cpu": {
[...]
"host": {
"host": "XXXXXXXX",
"machineid": "feb35e201XXXXXXXXXXXb6669919",
"server_key": "",
"distro": {
"version": "20",
"name": "fedora"
},
"ip_address": "XXXXXXXX",
"instance_id": ""
},
"plugins": {},
"checks": null
}INFO[0003] Sending data to http://amon.XXXXX/api/system/v2/?api_key=XXXXXXXXXXXXXXXXXXXXXXXX
open /etc/opt/amonagent/machine-id: permission deniedinvalid argumentINFO[0063] Metrics collected (Interval:1m0s)
{
"system": {
"cpu": {
"user": 0,
[...]
],
"host": {
"host": "XXXXXXX",
"machineid": "1b3da610XXXXXXX96646ebbd",
"server_key": "",
"distro": {
"version": "20",
"name": "fedora"
},
"ip_address": "XXXXXX",
"instance_id": ""
},
"plugins": {},
"checks": null
}INFO[0063] Sending data to http://amon.XXXXXX/api/system/v2/?api_key=XXXXXXXXXXXXXX
open /etc/opt/amonagent/machine-id: permission deniedinvalid argumentINFO[0123] Metrics collected (Interval:1m0s)
From an strace
:
openat(AT_FDCWD, "/proc/sys/kernel/hostname", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
read(3, "direct131ca\n", 512) = 12
close(3) = 0
stat64("/etc/opt/amonagent/machine-id", 0x18845b24) = -1 ENOENT (No such file or directory)
getrandom("\342\353P\372\361\364{\370*\345DQ\312\327w\344", 16, 0) = 16
openat(AT_FDCWD, "/etc/opt/amonagent/machine-id", O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE|O_CLOEXEC, 0666) = -1 EACCES (Permission denied)
write(1, "open /etc/opt/amonagent/machine-"..., 53open /etc/opt/amonagent/machine-id: permission denied) = 53
write(1, "invalid argument", 16invalid argument) = 16
openat(AT_FDCWD, "/etc/opt/amonagent/amonagent.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
read(3, "{\n \"api_key\":\"cxfsAQT4LXQPljW"..., 512) = 112
stat64("/etc/opt/amonagent/plugins-enabled", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
Ruby scripts dont run with amonagent service.. They only run if i call amonagent manually from command line.
I changed the startup script line 20 to DAEMON='/usr/bin/amonagent -debug
and also line 34 to STDOUT=/var/log/amonagent/amonagent.log
in order to log all the output to log fine and heres the output :
"checks": [ { "name": "", "command": "check-dir-size.rb -d /var/log/", "exit_code": 0, "output": "", "error": "exec: not started" }, { "name": "", "command": "check-qmailq.rb", "exit_code": 0, "output": "", "error": "exec: not started" } ]
Also some more info :
# su -s /bin/bash amonagent bash-4.1$ env HOSTNAME=xxx.xxx.com rvm_bin_path=/usr/local/rvm/bin GEM_HOME=/usr/local/rvm/gems/ruby-2.4.0 SHELL=/bin/bash MY_RUBY_HOME=/usr/local/rvm/rubies/ruby-2.4.0 SSH_TTY=/dev/pts/2 USER=amonagent rvm_path=/usr/local/rvm rvm_prefix=/usr/local PATH=/usr/local/rvm/gems/ruby-2.4.0/bin:/usr/local/rvm/gems/ruby-2.4.0@global/bin:/usr/local/rvm/rubies/ruby-2.4.0/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/rvm/bin:/root/bin MAIL=/var/spool/mail/root _=/bin/env PWD=/usr/local/rvm/gems/ruby-2.4.0/bin LANG=C _system_arch=x86_64 GEM_PATH=/usr/local/rvm/gems/ruby-2.4.0:/usr/local/rvm/gems/ruby-2.4.0@global LESSOPEN=||/usr/bin/lesspipe.sh %s RUBY_VERSION=ruby-2.4.0
and some more info :
` gem env
RubyGems Environment:
If i run manually #amonagent all ruby checks runs fine.
Tried to run the bin with supervisord but still no success..
Tried to put the full path of the rb file in checks.conf still no success.
Tried to put "ruby path" "rb file path" still nothing..
If i run amonagent -test-plugin=checks all report fine no errors there.. See output :
`$ whoami
amonagent
bash-4.1$ amonagent -test-plugin=checks
[{"name":"","command":"check-dir-size.rb -d /var/log/","exit_code":2,"output":"CheckDirSize CRITICAL: Directory /var/log/ is greater than 4,000,000 bytes [actual size: 28,671,141 bytes]\n","error":""} {"name":"","command":"check-qmailq.rb","exit_code":0,"output":"CheckQMAILQ OK: 0 messages in the remote queue\n","error":""}]
Executed in 91.506987ms`
Tried also the example in docs and the output is also empty :
"plugins": { "nginx": { "gauges": { "connections.active": 52, "connections.reading": 0, "connections.waiting": 48, "connections.writing": 1, "connections_total.accepts": 2261, "connections_total.handled": 2261, "requests_per_second": 2 } }, "sensu": {} }, "checks": [ {
but if i run /opt/amonagent/amonagent -test-plugin=sensu : "sensu": { "sensu.xxxxxx.com": { "gauges": { "gr_iostat.avg-cpu_pct_idle": "83.67", "gr_iostat.avg-cpu_pct_iowait": "0", "gr_iostat.avg-cpu_pct_nice": "0", "gr_iostat.avg-cpu_pct_steal": "0", "gr_iostat.avg-cpu_pct_system": "3.52", "gr_iostat.avg-cpu_pct_user": "12.81", "gr_iostat.loop0_avgqu-sz": "0", "gr_iostat.loop0_avgrq-sz": "8",
OS : Centos x64 6.9
tried both ruby 2.3 installed with rvm & also installed with rpm repo : https://www.softwarecollections.org/en/scls/rhscl/rh-ruby23/
on ubuntu x64 16.04 it runs fine..
Any idea on what the problem might be ?
We've been having some issues running amonagent on a Debian Jessie machine
It keeps getting killed by SIGPIPE
# systemctl status amonagent -l
โ amonagent.service - Starts and stops amonagent
Loaded: loaded (/lib/systemd/system/amonagent.service; enabled)
Active: inactive (dead) since Sun 2017-04-02 04:47:45 WEST; 1 day 3h ago
Docs: https://www.amon.cx/docs
Main PID: 14402 (code=killed, signal=PIPE)
Apr 03 08:39:58 amonagent[25552]: time="2017-04-03T08:39:58+01:00" level=info msg="Metrics collected (Interval:1m0s)\n"
Apr 03 08:39:59 amonagent[25552]: time="2017-04-03T08:39:59+01:00" level=info msg="Sending data to https://xx.amon.cx/api/system/v2/?api_key=xx\n"
Apr 03 08:40:58 amonagent[25552]: time="2017-04-03T08:40:58+01:00" level=info msg="Metrics collected (Interval:1m0s)\n"
Apr 03 08:40:59 amonagent[25552]: time="2017-04-03T08:40:59+01:00" level=info msg="Sending data to https://xx.amon.cx/api/system/v2/?api_key=xx\n"
Apr 03 08:41:58 amonagent[25552]: time="2017-04-03T08:41:58+01:00" level=info msg="Metrics collected (Interval:1m0s)\n"
Apr 03 08:41:59 amonagent[25552]: time="2017-04-03T08:41:59+01:00" level=info msg="Sending data to https://xx.amon.cx/api/system/v2/?api_key=xx\n"
Apr 03 08:42:58 amonagent[25552]: time="2017-04-03T08:42:58+01:00" level=info msg="Metrics collected (Interval:1m0s)\n"
Apr 03 08:42:59 amonagent[25552]: time="2017-04-03T08:42:59+01:00" level=info msg="Sending data to https://xx.amon.cx/api/system/v2/?api_key=xx\n"
Apr 03 08:43:58 amonagent[25552]: time="2017-04-03T08:43:58+01:00" level=info msg="Metrics collected (Interval:1m0s)\n"
Apr 03 08:43:59 amonagent[25552]: time="2017-04-03T08:43:59+01:00" level=info msg="Sending data to https://xx.amon.cx/api/system/v2/?api_key=xx\n"
It seems to be related to journald restarting (which drops the stdout pipe i guess), and since amon doesnt handle SIGPIPE is gets killed.
The default systemd config specifies Restart=on-failure
- systemd apparently doesnt consider this a failure.
The best way to handle this would probably be to handle SIGPIPE and exit gracefully with a non-zero exit code
Another option would be specifying Restart=always
in the systemd file (realisticly - you want the amon agent running always, right?)
(The systemd restarts seem to be caused by some sort of "hardware" (qemu, so virtual) issue - so it won't be super common, but it's probably good to handle this better)
Hi,
Any chance you could build an arm7 binary too?
Thanks.
Somehow ended up with this in the DB:
{
"_id": ObjectID("5817b16cc7827b0016135100"),
"ip_address": "10.9.xx.xx",
"distro": {
"version": "27",
"name": "fedora"
}
}
...instead of the usual:
{
"_id": ObjectID("58255cb39050f80016a82e62"),
"check_every": 60,
"name": "servername",
"tags": [],
"keep_data": 30,
"key": "3d1adf6fbedb0ef0adxxxxxxxxxxxx",
"date_created": 1478843571,
"uptime": "211 days 7 hours 23 minutes",
"last_check": 1531851870,
"ip_address": "10.xx.xx.xx",
"distro": {
"version": "7.5.1804",
"name": "centos"
}
}
This resulted in the following error when trying to access the global Pause Alerts page.
amon_1 | ERROR Internal Server Error: /alerts/pause/global/
amon_1 | Traceback (most recent call last):
amon_1 | File "/root/.pex/install/Django-1.7.11-py2.py3-none-any.whl.dc8612fe3bbe13c40d7a66002a1a4af1693a40e7/Django-1.7.11-py2.py3-none-any.whl/django/core/handlers/base.py", line 111, in get_response
amon_1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
amon_1 | File "/root/.pex/install/Django-1.7.11-py2.py3-none-any.whl.dc8612fe3bbe13c40d7a66002a1a4af1693a40e7/Django-1.7.11-py2.py3-none-any.whl/django/contrib/auth/decorators.py", line 21, in _wrapped_view
amon_1 | return view_func(request, *args, **kwargs)
amon_1 | File "/opt/amon/amon/apps/alerts/views/pause.py", line 33, in mute_servers
amon_1 | form = MuteForm()
amon_1 | File "/opt/amon/amon/apps/alerts/forms.py", line 104, in init
amon_1 | server_fields = [('all','All'),]+[(v['_id'],v['name']) for v in all_servers]
amon_1 | KeyError: 'name'
I am writing a SaltStack formula for Amon and am trying to include all platforms supported by it.
The Single binary collector agent
link the main page of amon.cx points me to this repo, which appears to be for linux only. Windows is not covered in the installation instructions either. I see that there is a 'amonagent-windows' repo, but there has been no work on it since Sep 25, 2015.
Is this still the still the prefered repo/method of installing the agent on windows?
Seems that at some point, whenever systemd evolved - it now able to follow up by himself over pid files.
And old start line of service that looks like
ExecStart=/usr/bin/amonagent -pidfile /var/run/amonagent/amonagent.pid
making amon to respawn multiple times in endless loop - and then to fail, when systemd decides that service is dead.
Changing service file to have this lines
ExecStart=/usr/bin/amonagent
PIDFile=/var/run/amonagent/amonagent.pid
brings up normal monitoring for systemd and single spawn of trackable service.
This seems to be happen only with newer version of amon >0.7.5 and Fedora 23 and up
Trying out current master (latest commit e9cf24b on Mar 27 2017) the "processes" object is not set.
With debug output enabled it looks like this:
{
"system": {
...
},
"processes": null,
"host": {
...
},
"plugins": {},
"checks": null
}
I see the '"processes": null,' on Ubuntu Linux 17.04 and Raspbian. I read that the processes listing isn't for Windows yet, but it should work for Linux - right?
I used 'go get github.com/amonapp/amonagent' and added the missing packages also with go get. I altered a path in makefile (building works fine) and altered address in the conf file to point to a local script that just writes down the POST data to a log file.
I am installing amonagent (just the agent) manually via a saltstack state.
In order to have the amonagent authenticate and be viewable at /servers/
on my amon server, I've noticed I have to issue:
/opt/amonagent/amonagent -test
Right after installation. Before that the error I was getting was:
2016/02/19 14:47:56 Starting Amon Agent (version 0.4.9)
2016/02/19 14:47:56 INFO amonagent.log Agent Config: Interval:1m0s
2016/02/19 14:47:59 INFO amonagent.log Metrics collected (Interval:1m0s)
2016/02/19 14:47:59 INFO amonagent.log Flusher routine failed, exiting: Can't connect to the Amon API on Can't connect to the Amon API on Post /api/system/v2/?api_key=: unsupported protocol scheme ""
After running the -test
option though, it runs though the checks, succeeds, and the servers immediately show up in the amon server UI.
Here is my amonagent salt state if you want to get an idea on the order / procedure i'm using to install amonagent by itself:
/srv/salt/amon/init.sls
#!py
def run():
api_key = __pillar__['amon.api_key']
amon_instance = __pillar__['amon.server']
states = {}
states['amonagent-repo'] = {
'pkgrepo.managed': [
{'humanname': 'Amon'},
{'name': 'deb http://packages.amon.cx/repo amon contrib'},
{'file': '/etc/apt/sources.list.d/amonagent.list'},
{'keyid': 'AD53961F'},
{'keyserver': 'hkp://keyserver.ubuntu.com:80'},
]
}
states['amonagent'] = {
'pkg.installed': [
{'require': [
{'pkgrepo': 'amonagent-repo'}
]}
]
}
context = {
'api_key': api_key,
'amon_instance': amon_instance
}
states['/etc/opt/amonagent/amonagent.conf'] = {
'file.managed': [
{'user': 'root'},
{'group': 'root'},
{'mode': 640},
{'source': 'salt://amon/files/amonagent.conf'},
{'context': context},
{'template': 'jinja'},
{'require': [
{'pkg': 'amonagent'}
]}
]
}
# PR https://github.com/amonapp/amonagent/pull/3 to fix typo upstream not merged yet
states['fix-init-script-typo'] = {
'file.replace': [
{'name': '/etc/init.d/amonagent'},
{'pattern': 'CONFING'},
{'repl': 'CONFIG'},
{'require': [
{'pkg': 'amonagent'}
]}
]
}
states['amonagent-running'] = {
'service.running': [
{'name': 'amonagent'},
{'require': [
{'file': 'fix-init-script-typo'}
]}
]
}
# seems that it needs this to fire off an initial auth request?
# it won't register in amon server until after i run this
states['amonagent-test'] = {
'cmd.run': [
{'name': '/opt/amonagent/amonagent -test'},
{'require': [
{'service': 'amonagent-running'}
]}
]
}
return states
Every time I restart the amon instance the amonagent on it doesn't start properly anymore. I then have to remove and reinstall the amonagent package to get it working again.
Any idea why this happens?
Installation is done with root, so I don't get the issue with the "permission denied".
Feb 1 19:43:02 mon amonagent[2718]: time="2018-02-01T19:43:02+01:00" level=info msg="Starting Amon Agent (Version: 0.7.5.3)\n"
Feb 1 19:43:02 mon amonagent[2718]: time="2018-02-01T19:43:02+01:00" level=fatal msg="Failed to verify pid directory mkdir /var/run/amonagent: permission denied"
amonagent appears to be sending bad check data to the amon server:
[~]# getent group amon
amon:x:397:
[~]# grep "amon" /etc/passwd
amon:x:995:397::/etc/opt/amon:/bin/false
amonagent:x:994:994::/etc/opt/amonagent:/bin/false
[~]# gem install sensu-plugins-process-checks
[~]# su -g amon -c "check-process.rb -p amonagent"
CheckProcess OK: Found 1 matching processes; cmd /amonagent/
[~]# su -s /bin/bash amon
bash-4.2$ whoami
amon
bash-4.2$ check-process.rb -p amonagent
CheckProcess OK: Found 1 matching processes; cmd /amonagent/
However when I go into the amon dashboard all amonagent checks are failing, with:
CheckProcess CRITICAL: Found 0 matching processes; cmd /amonagent/
I should also point out I am only seeing this issue with amonagent.
Describe the problem
in the file:
https://github.com/amonapp/amonagent/blob/966ce92533d05851b9b880be70f069d77d80438b/packaging/postinst.sh
at line 24, it should be "sudo systemctl start amonagent.service" instead "sudo systemctl start amonagent.service"
I know it's a only a text , but it can confuse people :)
Thanks!
When attempting to connect to mongodb database the following error is observed:
ERRO[0000] Can't connect to server': Unable to connect to URL (127.0.0.1:27017), server returned error on SASL authentication step: Invalid database name: '/admin'
It appears that the connection is not stripping the leading '/'
When dropping the database from the connection string it defaults to mgo's default database of test.
root@237001:~# /opt/amonagent/amonagent -debug -test-plugin=mysql
panic: runtime error: invalid memory address or nil pointer dereference
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x64b136]
goroutine 1 [running]:
panic(0x742e40, 0xc420012070)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
database/sql.(*Rows).Close(0x0, 0x0, 0x0)
/usr/local/go/src/database/sql/sql.go:1864 +0x26
panic(0x742e40, 0xc420012070)
/usr/local/go/src/runtime/panic.go:458 +0x243
database/sql.(*Rows).Next(0x0, 0x7ded78)
/usr/local/go/src/database/sql/sql.go:1752 +0x26
github.com/amonapp/amonagent/plugins/mysql.(*MySQL).Collect(0xc4200e4ec0, 0x0, 0x0, 0x0, 0x0)
/home/martin/go/src/github.com/amonapp/amonagent/plugins/mysql/mysql.go:287 +0x1d4c
github.com/amonapp/amonagent.(*Agent).TestPlugin(0xc4200e4f00, 0x7ffc0ba277e1, 0x5, 0xc42000b8c0, 0x28)
/home/martin/go/src/github.com/amonapp/amonagent/agent.go:35 +0x197
main.main()
/home/martin/go/src/github.com/amonapp/amonagent/cmd/amonagent.go:101 +0x2d0
My conf:
root@237001:~# cat /etc/opt/amonagent/plugins-enabled/mysql.conf
{"host": "wp:pass@/wp_anime"}
Error: Package: 1:amonagent-0.7.5.2-1.x86_64 (amon)
Requires: adduser
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
In the RPM repo there is only one version of the agent with a .noarch
designation (which seems wrong based on this). More importantly the version packaged in the RPM is 64-bit x86_64
and not 32-bit i686
.
On a 32 bit machine:
$ uname -a
Linux XXXXX 3.19.8-100.fc20.i686+PAE #1 SMP Tue May 12 17:27:49 UTC 2015 i686 i686 i386 GNU/Linux
$ file /bin/amonagent
/bin/amonagent: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
$ amonagent --version
-bash: /usr/bin/amonagent: cannot execute binary file
Available in the repo:
$ yum --showduplicates list amonagent
Loaded plugins: langpacks, refresh-packagekit
Installed Packages
amonagent.noarch 1:0.7-1 @amonagent
Available Packages
amonagent.noarch 1:0.2-1 amonagent
amonagent.noarch 1:0.2.1-1 amonagent
amonagent.noarch 1:0.2.2-1 amonagent
amonagent.noarch 1:0.2.3-1 amonagent
amonagent.noarch 1:0.2.4-1 amonagent
amonagent.noarch 1:0.2.5-1 amonagent
amonagent.noarch 1:0.2.6-1 amonagent
amonagent.noarch 1:0.2.7-1 amonagent
amonagent.noarch 1:0.2.8-1 amonagent
amonagent.noarch 1:0.2.8.1-1 amonagent
amonagent.noarch 1:0.2.8.2-1 amonagent
amonagent.noarch 1:0.2.8.3-1 amonagent
amonagent.noarch 1:0.2.8.4-1 amonagent
amonagent.noarch 1:0.2.9-1 amonagent
amonagent.noarch 1:0.3-1 amonagent
amonagent.noarch 1:0.4-1 amonagent
amonagent.noarch 1:0.4.1-1 amonagent
amonagent.noarch 1:0.4.2-1 amonagent
amonagent.noarch 1:0.4.3-1 amonagent
amonagent.noarch 1:0.4.4-1 amonagent
amonagent.noarch 1:0.4.5-1 amonagent
amonagent.noarch 1:0.4.6-1 amonagent
amonagent.noarch 1:0.4.7-1 amonagent
amonagent.noarch 1:0.4.8-1 amonagent
amonagent.noarch 1:0.4.9-1 amonagent
amonagent.noarch 1:0.6-1 amonagent
amonagent.noarch 1:0.6.1-1 amonagent
amonagent.noarch 1:0.6.2-1 amonagent
amonagent.noarch 1:0.6.3-1 amonagent
amonagent.noarch 1:0.6.4-1 amonagent
amonagent.noarch 1:0.6.5-1 amonagent
amonagent.noarch 1:0.7-1 amonagent
"Can't connect to the Amon API on Post
https:/amon/api/system/v2/<api key removed>: x509: certificate signed by unknown authority"
This could be done with the following Http config
var tr = &http.Transport{
ResponseHeaderTimeout: time.Duration(3 * time.Second),
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.