Project

aliyun-log

0.0
No release in over 3 years
Low commit activity in last 3 years
Aliyun Log SDK for Ruby 阿里云日志服务(SLS) Ruby SDK, 目前仅实现基于Restfull部分接口和简单Model映射
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.17
~> 12.3, >= 12.3.3
~> 3.0
~> 3.0

Runtime

 Project Readme

Aliyun::Log

阿里云简单日志服务(SLS) Ruby SDK Gem

目前支持的功能 API

项目相关:

  • 列表
  • 创建
  • 修改
  • 删除

Logstore 相关:

  • 列表
  • 创建
  • 修改
  • 删除

索引相关

  • 查看
  • 创建
  • 修改
  • 删除

日志相关

  • 查询
  • 创建日志
  • histograms

Model 映射

  • 支持简单 Model 映射
  • 类型显式 Cast 映射
  • Scope 简单支持
  • Select
  • Group
  • Count

TODO

  • 完善 Model 映射查询解析
  • 优化 Model 映射创建数据
  • 完善 restful 接口
  • 完善 Model 逻辑结构
  • 增加 消费组接口

Installation

Add this line to your application's Gemfile:

gem 'aliyun-log'

Include the following in your project or 'irb' command:

require 'aliyun/log'

And then execute:

$ bundle

Or install it yourself as:

$ gem install aliyun-log

Usage

[optional] Global configure

Aliyun::Log.configure do |config|
  config.access_key_id      = 'key_id'
  config.access_key_secret  = 'key_secret'
  config.endpoint  = 'https://cn-beijing.log.aliyuncs.com'
  config.log_file  = 'aliyun_log.log' # default
  # Logger::DEBUG | Logger::INFO | Logger::ERROR | Logger::FATAL
  config.log_level = Logger::DEBUG # default
end

In specific, the endpoint is the Log service address. The address may vary based on different regions for the node. The address for a Beijing node is: https://cn-beijing.log.aliyuncs.com by default configure. the endpoint also support for internal address just like normal address.

SDK

Create a client

client = Aliyun::Log::Client.new(
  endpoint: 'https://cn-beijing.log.aliyuncs.com',
  access_key_id: 'key_id',
  access_key_secret: 'key_secret'
)

# or using default global config
client = Aliyun::Log::Client.new

List projects

projects = client.list_projects # arguments(size = 500, offset = 0)
# => projects
{
  "count" => 0,
  "total" => 0,
  "projects" => [Aliyun::Log::Project#instance]
}
projects["projects"].each { |project| p project.name }

client.projects equal projects["projects"]

Get project

project = client.get_project('project_name')
# or
project = projects["projects"][0]

Delete project

client.delete_project('project_name')

Update project

client.update_project('project_name', 'project description')

List logstores

project.list_logstores # arguments(size = 500, offset = 0)
# =>
{
  "count"=>1,
  "logstores"=>["nginx_log"],
  "total"=>2
}

Get logstore

logstore = project.get_logstore('logstore_name')
logstore.name

Logstore index

logstore.get_index
logstore.create_index_line # only full text index
logstore.create_index(
  key1: {
    type: 'text',
  },
  key2: {
    type: 'long'
  }
)
logstore.update_index(
  key1: {
    type: 'text',
  },
  key2: {
    type: 'text'
  }
)
logstore.delete_index

Put logs

log = Aliyun::Log::Protobuf::Log.new(
  time: Time.now.to_i,
  contents: [{ key: "k1", value: "v1" }]
)
log_group = Aliyun::Log::Protobuf::LogGroup.new(
  logs: [log] # limit less than 4096 items and limit body less than 3mb
)
logstore.put_logs(log_group)

# Or simple kv log
logstore.put_log({ key1: "value1", key2: "value2" })
logstore.put_log([
  { key1: "value1", key2: "value2" },
  { key1: "value11", key2: "value22" }
], time: Time.now.to_i)

Get logs

logstore.get_logs(from: Time.now.to_i - 3600, to: Time.now.to_i)
logstore.get_logs(
  from: Time.now.to_i - 3600,
  to: Time.now.to_i,
  query: "*|select count(*), 'k1' as kk", # 'full text search or sql'
  line: 100,
  offset: 0,
  reverse: false,
  topic: '' # __topic__
)

Get log histograms

logstore.get_histograms(
  from: Time.now.to_i - 3600,
  to: Time.now.to_i,
  query: "*|select count(*), 'k1' as kk",
)

Model record

Aliyun::Log.configure do |c|
  config.timestamps = false # turn off created_at field
  config.project = 'user_logs' # project name
end

# defind model class
class User
  include Aliyun::Log::Record

  # @param name: default using class name pluralize
  # @param field_index: toggle all field indecies
  # @param project: logstore project name
  # @param auto_sync: logstore automation create, default true
  # @param field_doc_value: toggle all field analytic index, default true
  logstore name: 'users', field_index: true

  scope :children, -> { search('age <= 18') }

  scope :country , ->(name) { search("location: #{name}") }

  # @param 1: field name
  # @param type: text/long/double/json, default was text
  # @param cast_type: [:string, :integer, :float, :bigdecimal, :json, :date, :datetime]
  # @param index: index toggle, higher than logstore.field_index
  # @param default: default value
  # @param doc_value: toggle analytic index, default true
  # @param caseSensitive: toggle word case sensitive, default false
  # @param log_tag: toggle log_tag, default false
  field :age, type: :long, index: false
  field :time, type: :text, cast_type: :datetime, default: -> { Time.now }
  field :name, default: 'Dace'
  field :location, type: :text
  filed :__type__, log_tag: true

  # ActiveModel::Validations
  validates :name, :what, presence: true

  # ActiveModel::Callbacks
  # support [initialize create save] callbacks
  before_save do
    self.location = name * 2
  end
end

# sync logstore and indecies
Aliyun::Log.init_logstore

filter methods

User.from('2020-01-01') # log start time
User.to('2020-01-01 01:02:03') # log end time
User.limit(20) # default limit 100
User.page(30) # offset will set to 600
User.search('*').sql("SELECT name")
# Log Query: "*|SELECT name"
User.search(age: 18, location: 'beijing')
User.search("age = ? AND location = ?", 18, 'beijing')
# Log Query: "age: 18 and location: beijing|SELECT name"

# support chain responsibility
users = User.search('name: dace')
# pagination
users = users.page(1).limit(3).result
# result => [{"__source__"=>"", "__time__"=>"1591459200", "name"=>"dace"}]

# sql pagination
User.search('name: dace')
    .sql('SELECT name LIMIT 1,3')
    .result
# note:
# sql limit can't using with raw page() and limit()

# where using raw restful request
# https://help.aliyun.com/document_detail/29029.html
User.where(from: 0, to: Time.now.to_i, topic: 'topic3', line: 30).load

result functions

User.count
User.from(Date.yesterday).sql('select * where name is not null').count
# => 100
User.result
# => [{"__source__"=>"", "__time__"=>"1590000000", "__topic__"=>"", "created_at"=>"2020-06-08T16:36:17+08:00", "name"=>"Dace", "age"=>"28", "time"=>"2020-06-08T16:36:17+08:00", "location"=>"DaceDace"}]
User.load
# => [#<User created_at: "2020-06-08T18:39:03+08:00", name: "Dace", age: "28", location: "DaceDace">]
User.first
User.first(3)
User.last
User.last(3)
User.second
User.third
User.fourth
User.fifth

User.select('name, count(name)').group(:name).result
User.select(:name).order(:age).result

Logger

Log file in the directory of project root aliyun_log.log and level was Logger::DEBUG by default using global config.

logger and level

Aliyun::Log::Common::Logging.logger = Logger.new('aliyun.log')
Aliyun::Log::Common::Logging.loger_file = 'aliyun.log'

# Logger::DEBUG | Logger::INFO | Logger::ERROR | Logger::FATAL
Aliyun::Log::Common::Logging.log_level = Logger::INFO

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/yingce/aliyun-log. This project is intended to be a safe, welcoming space for collaboration

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Aliyun::Log project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.