SlideShare a Scribd company logo
1 of 17
Download to read offline
mruby で mackerel の
プラグインを作るはなし
今やるなら mruby
self.introduce
=>
{
name: “SHIBATA Hiroshi”,
nickname: “hsbt”,
title: “Chief engineer at GMO Pepabo, Inc.”,
commit_bits: [“ruby”, “rake”, “rubygems”, “rdoc”, “tdiary”,
“hiki”, “railsgirls”, “railsgirls-jp”, …],
sites: [“hsbt.org”, ruby-lang.org”, “rubyci.com”, “railsgirls.com”,
“railsgirls.jp”],
}
What’s mackerel plugin?
time series data
monitoring item
mackerel plugin format
•time series data
•tab separated value at stdout
•monitoring item
•nagios compatible results with exit status
Write cli tool using mruby-cli
see. https://github.com/hone/mruby-cli
1. Edit `build_config.rb` in top-level directory of mruby-cli
2. write mruby code into mrblib
3. build cli binary with docker or your development
platform
I think it’s too easily using mruby and mruby-redis at first.
NoMethodError…
> r = Redis.new '127.0.0.1', 6379
=> #<Redis:0x7fa109806230>
> r.scard
(mirb):3: undefined method 'scard' for #<Redis:0x7fa109806230> (NoMethodError)
> r.smember
(mirb):4: undefined method 'smember' for #<Redis:0x7fa109806230> (NoMethodError)
???
… mruby-redis is not support `Set` type function in redis.
We can make it
Reading mruby-redis
Checking out “https://github.com/matsumoto-r/mruby-redis”
and open Rakefile
MRUBY_CONFIG=File.expand_path(ENV["MRUBY_CONFIG"] || "build_config.rb")
(snip)
file :mruby do
(snip)
sh "git clone --depth=1 git://github.com/mruby/mruby.git"
end
desc "compile binary"
task :compile => :mruby do
sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} rake all"
end
(snip)
build_config.rb
MRuby::Build.new do |conf|
# load specific toolchain settings
toolchain :gcc
(snip)
conf.gembox 'default'
conf.gem File.expand_path(File.dirname(__FILE__))
conf.gem :github => 'matsumoto-r/mruby-sleep'
(snip)
end
Static link with hiredis
MRuby::Gem::Specification.new('mruby-redis') do |spec|
(snip)
hiredis_dir = "#{build_dir}/hiredis"
(snip)
if ! File.exists? hiredis_dir
Dir.chdir(build_dir) do
e = {}
run_command e, 'git clone git://github.com/redis/hiredis.git'
end
end
(snip)
spec.cc.include_paths << "#{hiredis_dir}/include"
spec.linker.flags_before_libraries << “#{hiredis_dir}/lib/libhiredis.a"
(snip)
end
Initialization point of native ext of mrbgem
see doc/guides/mrbgems.md on mruby/mruby
In src/mruby_redis.h on matsumoto-r/mruby-redis
mrb_YOURGEMNAME_gem_init(mrb_state)
ex. ruby-redis: mrb_mruby_redis_gem_init(mrb_state)
#ifndef MRB_REDIS_H
#define MRB_REDIS_H
void mrb_mruby_redis_gem_init(mrb_state *mrb);
#endif
Basic pattern of mruby class in C
void mrb_mruby_redis_gem_init(mrb_state *mrb)
{
struct RClass *redis;
redis = mrb_define_class(mrb, "Redis", mrb->object_class);
mrb_define_class_under(mrb, redis, "ConnectionError", E_RUNTIME_ERROR);
mrb_define_method(mrb, redis, "initialize", mrb_redis_connect, MRB_ARGS_ANY());
mrb_define_method(mrb, redis, "select", mrb_redis_select, MRB_ARGS_REQ(1));
(snip)
mrb_define_method(mrb, redis, "flushdb", mrb_redis_flushdb, MRB_ARGS_NONE());
(snip)
}
mrb_value mrb_redis_llen(mrb_state *mrb, mrb_value self)
{
mrb_value key;
mrb_int integer;
redisContext *rc = DATA_PTR(self);
mrb_get_args(mrb, "o", &key);
redisReply *rr = redisCommand(rc,"LLEN %s", mrb_str_to_cstr(mrb, key));
integer = rr->integer;
freeReplyObject(rr);
return mrb_fixnum_value(integer);
}
Write instance methods using C
Implementation of “scard” command
“scard" received key of target Set. It’s same as “llen”
Replaced “LLEN” to “SCARD”
SCARD return integer value of Set length
mrb_get_args(mrb, "o", &key);
redisReply *rr = redisCommand(rc,"SCARD %s", mrb_str_to_cstr(mrb, key));
integer = rr->integer;
return mrb_fixnum_value(integer);
mrb_define_method(mrb, redis, "scard", mrb_redis_scard, MRB_ARGS_REQ(1));
Implementation of “smember” command
mrb_value mrb_redis_smembers(mrb_state *mrb, mrb_value self)
{
int i;
mrb_value array, key;
redisContext *rc = DATA_PTR(self);
mrb_get_args(mrb, "o", &key);
redisReply *rr = redisCommand(rc, "SMEMBERS %s", mrb_str_to_cstr(mrb, key));
if (rr->type == REDIS_REPLY_ARRAY) {
array = mrb_ary_new(mrb);
for (i = 0; i < rr->elements; i++) {
mrb_ary_push(mrb, array, mrb_str_new(mrb, rr->element[i]->str, rr->element[i]->len));
}
} else {
freeReplyObject(rr);
return mrb_nil_value();
}
freeReplyObject(rr);
return array;
}
mackerel-plugin-sidekiq-job-count
https://github.com/hsbt/mackerel-plugin-sidekiq-job-count
def __main__(argv)
if argv[1] == "version"
puts "v#{SidekiqJobCount::VERSION}"
else
r = Redis.new argv[1], argv[2].to_i
namespace = argv[3]
key = ""
key += "#{namespace}:" if namespace
key += 'queues'
queues = r.smembers key
enqueued = queues.map{|queue| "#{key[0...-1]}:#{queue}" }.map{|k| r.llen k }.inject(0){|s, v| s + v}
r.close
puts "sidekiq_job_count.enqueuedt#{enqueued}t#{Time.now.to_i}"
end
end
It works!!1
[user@manage001 ~]$ /usr/local/bin/mackerel-plugin-sidekiq-job-count redis_host_name 6379 sidekiq
sidekiq_job_count.enqueued 0 1446624944

More Related Content

What's hot

Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 

What's hot (20)

Gemification plan of Standard Library on Ruby
Gemification plan of Standard Library on RubyGemification plan of Standard Library on Ruby
Gemification plan of Standard Library on Ruby
 
Leave end-to-end testing to Capybara
Leave end-to-end testing to CapybaraLeave end-to-end testing to Capybara
Leave end-to-end testing to Capybara
 
Dependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesDependency Resolution with Standard Libraries
Dependency Resolution with Standard Libraries
 
Gate of Agile Web Development
Gate of Agile Web DevelopmentGate of Agile Web Development
Gate of Agile Web Development
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
RubyGems 3 & 4
RubyGems 3 & 4RubyGems 3 & 4
RubyGems 3 & 4
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of Ruby
 
D2
D2D2
D2
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
Rails Performance
Rails PerformanceRails Performance
Rails Performance
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with Examples
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
All aboard the NodeJS Express
All aboard the NodeJS ExpressAll aboard the NodeJS Express
All aboard the NodeJS Express
 
vert.x 소개 및 개발 실습
vert.x 소개 및 개발 실습vert.x 소개 및 개발 실습
vert.x 소개 및 개발 실습
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
 

Viewers also liked

超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)
超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)
超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)
mametter
 

Viewers also liked (20)

Ember コミュニティとわたし
Ember コミュニティとわたしEmber コミュニティとわたし
Ember コミュニティとわたし
 
WebSocket For Web Rubyists
WebSocket For Web RubyistsWebSocket For Web Rubyists
WebSocket For Web Rubyists
 
Rubyで実はwritev(2) が使われているはなし
Rubyで実はwritev(2) が使われているはなしRubyで実はwritev(2) が使われているはなし
Rubyで実はwritev(2) が使われているはなし
 
SQL 脳から見た Ruby
SQL 脳から見た RubySQL 脳から見た Ruby
SQL 脳から見た Ruby
 
超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)
超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)
超絶技巧プログラミングと Ruby 3.0 (大江戸 Ruby 会議 05 コミッタ LT)
 
Security Advisories Checker on Travis/Circle CI
Security Advisories Checker on Travis/Circle CISecurity Advisories Checker on Travis/Circle CI
Security Advisories Checker on Travis/Circle CI
 
BigQueryのちょっとした話 #phpblt
BigQueryのちょっとした話 #phpbltBigQueryのちょっとした話 #phpblt
BigQueryのちょっとした話 #phpblt
 
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
 
GitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO PepaboGitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO Pepabo
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby Core
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略
 
Composer並列化プラグイン #phpblt
Composer並列化プラグイン #phpblt Composer並列化プラグイン #phpblt
Composer並列化プラグイン #phpblt
 
The story of language development
The story of language developmentThe story of language development
The story of language development
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutes
 
Learning to forget continual prediction with lstm
Learning to forget continual prediction with lstmLearning to forget continual prediction with lstm
Learning to forget continual prediction with lstm
 
Usecase examples of Packer
Usecase examples of Packer Usecase examples of Packer
Usecase examples of Packer
 
技術的負債との付き合い方
技術的負債との付き合い方技術的負債との付き合い方
技術的負債との付き合い方
 
Developing the fastest HTTP/2 server
Developing the fastest HTTP/2 serverDeveloping the fastest HTTP/2 server
Developing the fastest HTTP/2 server
 
Tochigi07 cm
Tochigi07 cmTochigi07 cm
Tochigi07 cm
 

Similar to mruby で mackerel のプラグインを作るはなし

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Nick Sieger
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
Raimonds Simanovskis
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
GUI Programming with MacRuby
GUI Programming with MacRubyGUI Programming with MacRuby
GUI Programming with MacRuby
Erik Berlin
 
Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...
Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...
Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...
Alexander Dymo
 

Similar to mruby で mackerel のプラグインを作るはなし (20)

RubyGems 3 & 4
RubyGems 3 & 4RubyGems 3 & 4
RubyGems 3 & 4
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRuby
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
How to control physical devices with mruby
How to control physical devices with mrubyHow to control physical devices with mruby
How to control physical devices with mruby
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
Damage Control
Damage ControlDamage Control
Damage Control
 
Gems on Ruby
Gems on RubyGems on Ruby
Gems on Ruby
 
Rails with mongodb
Rails with mongodbRails with mongodb
Rails with mongodb
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
 
Oracle adapters for Ruby ORMs
Oracle adapters for Ruby ORMsOracle adapters for Ruby ORMs
Oracle adapters for Ruby ORMs
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 
GUI Programming with MacRuby
GUI Programming with MacRubyGUI Programming with MacRuby
GUI Programming with MacRuby
 
Gdb basics for my sql db as (percona live europe 2019)
Gdb basics for my sql db as (percona live europe 2019)Gdb basics for my sql db as (percona live europe 2019)
Gdb basics for my sql db as (percona live europe 2019)
 
Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...
Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...
Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover ...
 
Deploying Machine Learning Models to Production
Deploying Machine Learning Models to ProductionDeploying Machine Learning Models to Production
Deploying Machine Learning Models to Production
 
Openshift operator insight
Openshift operator insightOpenshift operator insight
Openshift operator insight
 

More from Hiroshi SHIBATA

More from Hiroshi SHIBATA (20)

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?
 
Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発
 
Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?
 
RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?
 
The details of CI/CD environment for Ruby
The details of CI/CD environment for RubyThe details of CI/CD environment for Ruby
The details of CI/CD environment for Ruby
 
Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard Way
 
OSS Security the hard way
OSS Security the hard wayOSS Security the hard way
OSS Security the hard way
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of Ruby
 
The Future of Dependency Management for Ruby
The Future of Dependency Management for RubyThe Future of Dependency Management for Ruby
The Future of Dependency Management for Ruby
 
The Future of Bundled Bundler
The Future of Bundled BundlerThe Future of Bundled Bundler
The Future of Bundled Bundler
 
What's new in RubyGems3
What's new in RubyGems3What's new in RubyGems3
What's new in RubyGems3
 
Productive Organization with Ruby
Productive Organization with RubyProductive Organization with Ruby
Productive Organization with Ruby
 
Gems on Ruby
Gems on RubyGems on Ruby
Gems on Ruby
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

mruby で mackerel のプラグインを作るはなし

  • 1. mruby で mackerel の プラグインを作るはなし 今やるなら mruby
  • 2. self.introduce => { name: “SHIBATA Hiroshi”, nickname: “hsbt”, title: “Chief engineer at GMO Pepabo, Inc.”, commit_bits: [“ruby”, “rake”, “rubygems”, “rdoc”, “tdiary”, “hiki”, “railsgirls”, “railsgirls-jp”, …], sites: [“hsbt.org”, ruby-lang.org”, “rubyci.com”, “railsgirls.com”, “railsgirls.jp”], }
  • 3. What’s mackerel plugin? time series data monitoring item
  • 4. mackerel plugin format •time series data •tab separated value at stdout •monitoring item •nagios compatible results with exit status
  • 5. Write cli tool using mruby-cli see. https://github.com/hone/mruby-cli 1. Edit `build_config.rb` in top-level directory of mruby-cli 2. write mruby code into mrblib 3. build cli binary with docker or your development platform I think it’s too easily using mruby and mruby-redis at first.
  • 6. NoMethodError… > r = Redis.new '127.0.0.1', 6379 => #<Redis:0x7fa109806230> > r.scard (mirb):3: undefined method 'scard' for #<Redis:0x7fa109806230> (NoMethodError) > r.smember (mirb):4: undefined method 'smember' for #<Redis:0x7fa109806230> (NoMethodError) ??? … mruby-redis is not support `Set` type function in redis.
  • 8. Reading mruby-redis Checking out “https://github.com/matsumoto-r/mruby-redis” and open Rakefile MRUBY_CONFIG=File.expand_path(ENV["MRUBY_CONFIG"] || "build_config.rb") (snip) file :mruby do (snip) sh "git clone --depth=1 git://github.com/mruby/mruby.git" end desc "compile binary" task :compile => :mruby do sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} rake all" end (snip)
  • 9. build_config.rb MRuby::Build.new do |conf| # load specific toolchain settings toolchain :gcc (snip) conf.gembox 'default' conf.gem File.expand_path(File.dirname(__FILE__)) conf.gem :github => 'matsumoto-r/mruby-sleep' (snip) end
  • 10. Static link with hiredis MRuby::Gem::Specification.new('mruby-redis') do |spec| (snip) hiredis_dir = "#{build_dir}/hiredis" (snip) if ! File.exists? hiredis_dir Dir.chdir(build_dir) do e = {} run_command e, 'git clone git://github.com/redis/hiredis.git' end end (snip) spec.cc.include_paths << "#{hiredis_dir}/include" spec.linker.flags_before_libraries << “#{hiredis_dir}/lib/libhiredis.a" (snip) end
  • 11. Initialization point of native ext of mrbgem see doc/guides/mrbgems.md on mruby/mruby In src/mruby_redis.h on matsumoto-r/mruby-redis mrb_YOURGEMNAME_gem_init(mrb_state) ex. ruby-redis: mrb_mruby_redis_gem_init(mrb_state) #ifndef MRB_REDIS_H #define MRB_REDIS_H void mrb_mruby_redis_gem_init(mrb_state *mrb); #endif
  • 12. Basic pattern of mruby class in C void mrb_mruby_redis_gem_init(mrb_state *mrb) { struct RClass *redis; redis = mrb_define_class(mrb, "Redis", mrb->object_class); mrb_define_class_under(mrb, redis, "ConnectionError", E_RUNTIME_ERROR); mrb_define_method(mrb, redis, "initialize", mrb_redis_connect, MRB_ARGS_ANY()); mrb_define_method(mrb, redis, "select", mrb_redis_select, MRB_ARGS_REQ(1)); (snip) mrb_define_method(mrb, redis, "flushdb", mrb_redis_flushdb, MRB_ARGS_NONE()); (snip) }
  • 13. mrb_value mrb_redis_llen(mrb_state *mrb, mrb_value self) { mrb_value key; mrb_int integer; redisContext *rc = DATA_PTR(self); mrb_get_args(mrb, "o", &key); redisReply *rr = redisCommand(rc,"LLEN %s", mrb_str_to_cstr(mrb, key)); integer = rr->integer; freeReplyObject(rr); return mrb_fixnum_value(integer); } Write instance methods using C
  • 14. Implementation of “scard” command “scard" received key of target Set. It’s same as “llen” Replaced “LLEN” to “SCARD” SCARD return integer value of Set length mrb_get_args(mrb, "o", &key); redisReply *rr = redisCommand(rc,"SCARD %s", mrb_str_to_cstr(mrb, key)); integer = rr->integer; return mrb_fixnum_value(integer); mrb_define_method(mrb, redis, "scard", mrb_redis_scard, MRB_ARGS_REQ(1));
  • 15. Implementation of “smember” command mrb_value mrb_redis_smembers(mrb_state *mrb, mrb_value self) { int i; mrb_value array, key; redisContext *rc = DATA_PTR(self); mrb_get_args(mrb, "o", &key); redisReply *rr = redisCommand(rc, "SMEMBERS %s", mrb_str_to_cstr(mrb, key)); if (rr->type == REDIS_REPLY_ARRAY) { array = mrb_ary_new(mrb); for (i = 0; i < rr->elements; i++) { mrb_ary_push(mrb, array, mrb_str_new(mrb, rr->element[i]->str, rr->element[i]->len)); } } else { freeReplyObject(rr); return mrb_nil_value(); } freeReplyObject(rr); return array; }
  • 16. mackerel-plugin-sidekiq-job-count https://github.com/hsbt/mackerel-plugin-sidekiq-job-count def __main__(argv) if argv[1] == "version" puts "v#{SidekiqJobCount::VERSION}" else r = Redis.new argv[1], argv[2].to_i namespace = argv[3] key = "" key += "#{namespace}:" if namespace key += 'queues' queues = r.smembers key enqueued = queues.map{|queue| "#{key[0...-1]}:#{queue}" }.map{|k| r.llen k }.inject(0){|s, v| s + v} r.close puts "sidekiq_job_count.enqueuedt#{enqueued}t#{Time.now.to_i}" end end
  • 17. It works!!1 [user@manage001 ~]$ /usr/local/bin/mackerel-plugin-sidekiq-job-count redis_host_name 6379 sidekiq sidekiq_job_count.enqueued 0 1446624944