aliyun_sls 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c73284b6f778826dc960bb7658a8afc0d746575
4
+ data.tar.gz: 0f9b584ff1d6c1793ac7892691fcca8d5c0e1a80
5
+ SHA512:
6
+ metadata.gz: b1f74d011a320926289ecd1df1520a09a419ebc3a5b62c7470ba02f746882b497d62e1246c9a14144e5da62e8b1b5446d8909357dbe3efae79aaf0471b458261
7
+ data.tar.gz: b7345690159e33083a2c8b142bea93cef5c0df254a9db6999f9881a5218bbe826fe12edabc87a4b84a50841b4ad995bb285a3ab77d28bc3d24fe0cb466a444ab
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in aliyun_sls.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 cuizheng
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # AliyunSls
2
+
3
+ ## 阿里云SLS服务Ruby SDK
4
+
5
+ 简单日志服务(Simple Log Service,简称SLS)是针对日志收集、存储和查询的平台化服务。服务提供各种类型日志的实时收集,平台化存储及实时查询海量的日志。并可以将日志归档至ODPS,以利用ODPS做大数据分析。除了通过管理控制台操作,SLS还提供了API(Application Programming Interface)方式写入、查询日志数据,管理自己的项目及日志库等。
6
+
7
+ #### SLS(简单日志服务)[介绍](http://docs.aliyun.com/?spm=5176.730001.3.10.5GpxDL#/sls)
8
+
9
+ ------------
10
+ ## 库用法
11
+
12
+ ### 查询Store清单(ListLogstores)
13
+
14
+ con = AliyunSls::Connection.new("project", "region", "access_key_secret", "aliyun_access_key")
15
+ con.list_logstores
16
+
17
+ ### 上传日志(PutLogs)
18
+
19
+ log = AliyunSls::Protobuf::Log.new(:time => Time.now.to_i, :contents => [])
20
+
21
+ [
22
+ ['value1', '12'],
23
+ ['value2', '24'],
24
+ ['value3', '36'],
25
+ ['value4', '48']
26
+ ].each { |e|
27
+ k = e[0]
28
+ v = e[1]
29
+ log_item = AliyunSls::Protobuf::Log::Content.new(:key => k, :value => v)
30
+ log.contents << log_item
31
+ }
32
+ log_list = AliyunSls::Protobuf::LogGroup.new(:logs => [])
33
+ log_list.logs << log
34
+
35
+ con = AliyunSls::Connection.new("project", "region", "access_key_secret", "aliyun_access_key")
36
+ con.puts_logs("store", log_list)
37
+
38
+ ### TODO
39
+
40
+ - `ListTopics` 列出Logstore中的日志主题。
41
+ - `GetHistograms` 查询Logstore中的日志在时间轴上的分布。
42
+ - `GetLogs` 查询Logstore中的日志数据。
43
+
44
+ ## 命令行用法
45
+
46
+ 1. 生成配置文件
47
+ 2. `PROJECT=[PROJECT] REGION=[REGION] SECRET=[SECRET] KEY=[KEY] sls setup`
48
+ 1. 执行上传日志操作
49
+ 2. `[PROJECT=[PROJECT]] sls put log_path store [topic]`
50
+ 2. 上传日志操作是使用Tail方式执行,有增量日志产生的时候,会自动收集增量部分上传到阿里云
51
+
52
+ ## Installation
53
+
54
+ Add this line to your application's Gemfile:
55
+
56
+ gem 'aliyun_sls'
57
+
58
+ And then execute:
59
+
60
+ $ bundle
61
+
62
+ Or install it yourself as:
63
+
64
+ $ gem install aliyun_sls
65
+
66
+ ## Usage
67
+
68
+ TODO: Write usage instructions here
69
+
70
+ ## Contributing
71
+
72
+ 1. Fork it
73
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
74
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
75
+ 4. Push to the branch (`git push origin my-new-feature`)
76
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aliyun_sls/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aliyun_sls"
8
+ spec.version = AliyunSls::VERSION
9
+ spec.authors = ["cuizheng"]
10
+ spec.email = ["zheng.cuizh@gmail.com"]
11
+ spec.description = %q{Gem for SLS of Aliyun}
12
+ spec.summary = %q{Gem for SLS of Aliyun}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_dependency "rest-client"
24
+ spec.add_dependency "beefcake"
25
+ spec.add_dependency "file-tail"
26
+ spec.add_dependency "ruby-hmac"
27
+ end
data/bin/sls ADDED
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'aliyun_sls.rb')
3
+ require "file-tail"
4
+ require "byebug"
5
+ puts "sls [opt] ..." if (ARGV.size < 1)
6
+
7
+ def setup
8
+ h = {}
9
+ h['project'] = ENV["PROJECT"]
10
+ h['region'] = ENV["REGION"] || (puts "PROJECT=[PROJECT] REGION=[REGION] SECRET=[SECRET] KEY=[KEY] sls setup";exit)
11
+ h['access_key_secret'] = ENV["SECRET"] || (puts "PROJECT=[PROJECT] REGION=[REGION] SECRET=[SECRET] KEY=[KEY] sls setup";exit)
12
+ h['aliyun_access_key'] = ENV["KEY"] || (puts "PROJECT=[PROJECT] REGION=[REGION] SECRET=[SECRET] KEY=[KEY] sls setup";exit)
13
+ File.open(File.join(Dir.home, '.slsrc'), 'w+'){|f|
14
+ f << YAML.dump(h)
15
+ }
16
+ puts "setup config at ~/.slsrc"
17
+ end
18
+
19
+ def load
20
+ File.open(File.join(Dir.home, '.slsrc')){|f|
21
+ $config = YAML.load(f)
22
+ }
23
+ end
24
+
25
+ def regist_exit
26
+ puts "Press CTRL-C to quit"
27
+ Signal.trap(:INT){
28
+ exit(-1)
29
+ }
30
+ end
31
+
32
+ def put_logs(path, store, topic)
33
+ regist_exit
34
+ (puts "[PROJECT=[PROJECT]] sls put log_path store [topic]";exit(-1)) if !path || !store
35
+ load
36
+ (puts "load config failed! run: sls setup first.";exit(-1)) if !$config
37
+
38
+ # 如果传递了项目名称
39
+ # 则使用本次调用传递过来的值
40
+ # 否则使用配置文件中的值
41
+ con = AliyunSls::Connection.new(ENV['PROJECT'] || $config['project'], $config['region'], $config['access_key_secret'], $config['aliyun_access_key'])
42
+
43
+ File.open(path) do |log|
44
+ log.extend(File::Tail)
45
+ log.interval = 3
46
+ log.backward(0)
47
+ log.tail { |line|
48
+ puts line
49
+ put_line(line, con, store, topic)
50
+ }
51
+ end
52
+ end
53
+
54
+ def put_line(line, con, store, topic)
55
+ log = AliyunSls::Protobuf::Log.new(:time => Time.now.to_i, :contents => [])
56
+ begin
57
+ uri = URI.parse(line)
58
+ uri.query and uri.query.split('&').each{|paire|
59
+ k, v = paire.split('=')
60
+ log_item = AliyunSls::Protobuf::Log::Content.new(:key => k, :value => v)
61
+ log.contents << log_item
62
+ }
63
+ log_list = AliyunSls::Protobuf::LogGroup.new(:logs => [])
64
+ log_list.logs << log
65
+ log_list.topic = topic
66
+ log_list.source = uri.host
67
+ rescue URI::InvalidURIError => e
68
+ puts e
69
+ return
70
+ end
71
+
72
+ begin
73
+ rsp = con.puts_logs(store, log_list)
74
+ rescue Exception => e
75
+ puts "Exception with rsp #{e}"
76
+ end
77
+ end
78
+
79
+ case opt = ARGV[0]
80
+ when /setup/i
81
+ setup
82
+ exit(0)
83
+ when /put/i
84
+ put_logs(ARGV[1], ARGV[2], ARGV[3] || 'aliyun_sls_topic')
85
+ end
@@ -0,0 +1,157 @@
1
+ require 'rest_client'
2
+ require 'hmac-sha1'
3
+ require "base64"
4
+ require "zlib"
5
+
6
+ # log = AliyunSls::Protobuf::Log.new(:time => Time.now.to_i, :contents => [])
7
+
8
+ # [
9
+ # ['value1', '12'],
10
+ # ['value2', '24'],
11
+ # ['value3', '36'],
12
+ # ['value4', '48']
13
+ # ].each { |e|
14
+ # k = e[0]
15
+ # v = e[1]
16
+ # log_item = AliyunSls::Protobuf::Log::Content.new(:key => k, :value => v)
17
+ # log.contents << log_item
18
+ # }
19
+ # log_list = AliyunSls::Protobuf::LogGroup.new(:logs => [])
20
+ # log_list.logs << log
21
+
22
+ # con = AliyunSls::Connection.new("project", "region", "access_key_secret", "aliyun_access_key")
23
+ # con.puts_logs("store", log_list)
24
+
25
+ # con = AliyunSls::Connection.new("project", "region", "access_key_secret", "aliyun_access_key")
26
+ # con.list_logstores
27
+
28
+ module AliyunSls
29
+ class Connection
30
+ # region:
31
+ # 杭州:cn-hangzhou.sls.aliyuncs.com
32
+ # 青岛:cn-qingdao.sls.aliyuncs.com
33
+ # 北京:cn-beijing.sls.aliyuncs.com
34
+ # 深圳:cn-shenzhen.sls.aliyuncs.com
35
+ def initialize(project, region, access_key_secret, aliyun_access_key, opts={})
36
+ default_headers = {
37
+ "x-sls-apiversion" => "0.4.0",
38
+ "x-sls-signaturemethod" => "hmac-sha1"
39
+ }
40
+ @headers = default_headers.update opts
41
+ @aliyun_access_key = aliyun_access_key
42
+ @access_key_secret = access_key_secret
43
+ @host = "#{project}.#{region}"
44
+ end
45
+
46
+ def string_to_sign(verb, logstorename, headers, content, query={})
47
+ if content
48
+ string_to_sign_with_content(verb, logstorename, headers, query)
49
+ else
50
+ string_to_sign_without_content(verb, logstorename, headers, query)
51
+ end
52
+ end
53
+
54
+ def string_to_sign_with_content(verb, logstorename, headers, query={})
55
+ <<-DOC
56
+ #{verb}
57
+ #{headers['Content-MD5']}
58
+ #{headers['Content-Type']}
59
+ #{headers['Date']}
60
+ #{canonicalized_sls_headers(headers)}
61
+ #{canonicalized_resource(logstorename, query)}
62
+ DOC
63
+ end
64
+
65
+ def string_to_sign_without_content(verb, logstorename, headers, query={})
66
+ <<-DOC
67
+ #{verb}
68
+
69
+
70
+ #{headers['Date']}
71
+ #{canonicalized_sls_headers(headers)}
72
+ #{canonicalized_resource(logstorename, query)}
73
+ DOC
74
+ end
75
+
76
+ # “CanonicalizedSLSHeaders”的构造方式如下:
77
+ # 1. 将所有以“x-sls-”为前缀的HTTP请求头的名字转换成小写字母;
78
+ # 2. 将上一步得到的所有SLS自定义请求头按照字典序进行升序排序;
79
+ # 3. 删除请求头和内容之间分隔符两端出现的任何空格;
80
+ # 4. 将所有的头和内容用\n分隔符组合成最后的CanonicalizedSLSHeader;
81
+ def canonicalized_sls_headers(headers)
82
+ h = {}
83
+ headers.each { |k, v|
84
+ if k =~ /x-sls-.*/
85
+ h[k.downcase] = v
86
+ end
87
+ }
88
+ h.keys.sort.map { |e|
89
+ h[e]
90
+ "#{e}:#{h[e].gsub(/^\s+/,'')}"
91
+ }.join($/)
92
+ end
93
+
94
+ # “CanonicalizedResource”的构造方式如下:
95
+ # 1. 将CanonicalizedResource设置为空字符串("");
96
+ # 2. 放入要访问的SLS资源:"/logstores/logstorename"(无logstorename则不填);
97
+ # 3. 如请求包含查询字符串(QUERY_STRING),则在CanonicalizedResource字符串尾部添加“?”和查询字符串。
98
+ def canonicalized_resource(logstorename, query={})
99
+ u = logstorename ? URI.parse("/logstores/#{logstorename}") : URI.parse("/logstores")
100
+ if query.size != 0
101
+ u.query = query.inject([]){|s, a| s << "#{a[0]}=#{a[1]}"}.join('&')
102
+ end
103
+ u.to_s
104
+ end
105
+
106
+ # 目前,SLS API只支持一种数字签名算法,即默认签名算法"hmac-sha1"。其整个签名公式如下:
107
+ # Signature = base64(hmac-sha1(UTF8-Encoding-Of(SignString),AccessKeySecret))
108
+ def sign(verb, logstorename, headers, content, query)
109
+ Base64.encode64((HMAC::SHA1.new(@access_key_secret) << string_to_sign(verb, logstorename, headers, content, query).chomp).digest).strip
110
+ end
111
+
112
+ def signature(verb, logstorename, headers, content, query)
113
+ "SLS #{@aliyun_access_key}:#{sign(verb, logstorename, headers, content, query)}"
114
+ end
115
+
116
+ # content是LogGroup
117
+ def compact_headers(content, compressed)
118
+ headers = @headers.dup
119
+ # headers["x-sls-date"] =
120
+ headers["Date"] = DateTime.now.httpdate
121
+ headers["x-sls-bodyrawsize"] = "0"
122
+
123
+ if content and compressed
124
+ body = content.encode.to_s
125
+ headers["Content-Length"] = compressed.bytesize.to_s
126
+ # 日志内容包含的日志必须小于3MB和4096条。
127
+ raise AliyunSls::PostBodyTooLarge, "content length is larger than 3MB" if headers["Content-Length"].to_i > 3*1024**2*8
128
+ raise AliyunSls::PostBodyTooLarge, "content size is more than 4096" if content.logs.size > 4096
129
+ # MD5必须为大写字符串
130
+ headers["Content-MD5"] = Digest::MD5.hexdigest(compressed).upcase
131
+ headers["Content-Type"] = "application/x-protobuf"
132
+ headers["x-sls-bodyrawsize"] = body.bytesize.to_s
133
+ headers["x-sls-compresstype"] = "deflate"
134
+ end
135
+ headers
136
+ end
137
+
138
+ def puts_logs(logstorename, content)
139
+ # 压缩content数据
140
+ compressed = Zlib::Deflate.deflate(content.encode.to_s)
141
+ headers = compact_headers(content, compressed)
142
+ headers["Authorization"] = signature("POST", logstorename, headers, content, {})
143
+
144
+ u = URI.parse("http://#{@host}/logstores/#{logstorename}")
145
+ RestClient.post u.to_s, compressed, headers
146
+ end
147
+
148
+ def list_logstores
149
+ headers = compact_headers(nil, nil)
150
+ headers["Authorization"] = signature("GET", nil, headers, nil, {})
151
+
152
+ u = URI.parse("http://#{@host}/logstores")
153
+ headers["Referer"] = u.to_s
154
+ RestClient.get u.to_s, headers
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,50 @@
1
+ require 'beefcake'
2
+
3
+ module AliyunSls
4
+ module Protobuf
5
+
6
+ # message Log
7
+ # {
8
+ # required uint32 time = 1; // UNIX Time Format
9
+ # message Content
10
+ # {
11
+ # required string key = 1;
12
+ # required string value = 2;
13
+ # }
14
+ # repeated Content contents= 2;
15
+ # }
16
+
17
+ # message LogGroup
18
+ # {
19
+ # repeated Log logs= 1;
20
+ # optional string reserved =2; // 内部字段,不需要填写
21
+ # optional string topic = 3;
22
+ # optional string source = 4;
23
+ # }
24
+
25
+ class Log
26
+ include Beefcake::Message
27
+
28
+ required :time, :uint32, 1
29
+
30
+ class Content
31
+ include Beefcake::Message
32
+
33
+ required :key, :string, 1
34
+ required :value, :string, 2
35
+ end
36
+
37
+ repeated :contents, Content, 2
38
+ end
39
+
40
+ class LogGroup
41
+ include Beefcake::Message
42
+
43
+ repeated :logs, Log, 1
44
+ optional :reserved, :string, 2
45
+ optional :topic, :string, 3
46
+ optional :source, :string, 4
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module AliyunSls
2
+ VERSION = "0.0.2"
3
+ end
data/lib/aliyun_sls.rb ADDED
@@ -0,0 +1,13 @@
1
+ require File.join(File.dirname(__FILE__), 'aliyun_sls', 'version.rb')
2
+ require File.join(File.dirname(__FILE__), 'aliyun_sls', 'protobuf.rb')
3
+ require File.join(File.dirname(__FILE__), 'aliyun_sls', 'connection.rb')
4
+
5
+ module AliyunSls
6
+ class PostBodyInvalid < RuntimeError; end
7
+ class SLSInvalidTimestamp < RuntimeError; end
8
+ class SLSInvalidEncoding < RuntimeError; end
9
+ class SLSInvalidKey < RuntimeError; end
10
+ class PostBodyTooLarge < RuntimeError; end
11
+ class PostBodyUncompressError < RuntimeError; end
12
+ class SLSLogStoreNotExist < RuntimeError; end
13
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aliyun_sls
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - cuizheng
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: beefcake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: file-tail
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ruby-hmac
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Gem for SLS of Aliyun
98
+ email:
99
+ - zheng.cuizh@gmail.com
100
+ executables:
101
+ - sls
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - aliyun_sls.gemspec
111
+ - bin/sls
112
+ - lib/aliyun_sls.rb
113
+ - lib/aliyun_sls/connection.rb
114
+ - lib/aliyun_sls/protobuf.rb
115
+ - lib/aliyun_sls/version.rb
116
+ homepage: ''
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.0.6
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Gem for SLS of Aliyun
140
+ test_files: []
141
+ has_rdoc: