12/08/2018, 16:14

Develop buffalo-logs gem

Introduction https://rubygems.org/gems/buffalo-logs https://github.com/oTranQuangTrung/buffalo-logs Bắt nguồn từ 1 ý tưởng của @Nguyen.Thanh.Luan. Hôm nay mình sẽ viết một bài giới thiệu về 1 gem của mình viết và cách viết một gem Đây là 1 thư viện giúp project chúng ta extract log với ...

Introduction

https://rubygems.org/gems/buffalo-logs https://github.com/oTranQuangTrung/buffalo-logs Bắt nguồn từ 1 ý tưởng của @Nguyen.Thanh.Luan. Hôm nay mình sẽ viết một bài giới thiệu về 1 gem của mình viết và cách viết một gem Đây là 1 thư viện giúp project chúng ta extract log với level=error ra 1 file riêng nhằm giải quyết 1 vấn đề khi bất cứ ai test hệ thống thì tất cả log được lưu chung vào 1 file, làm cho việc cuộn log để đọc lỗi do đâu mất nhiều thời gian. Chúng ta chỉ cần vào file log lỗi để xem code mình đang gặp phải những vấn đề gì.

Implement

Sau khi cài đặt ruby, và gem bundler bằng command gem install bundler Ta sẽ tạo ta khung cơ bản của 1 gem bằng command bundle gem buffalo-logs. Ở đây tên gem của mình là buffalo-logs.

.
├── bin
│   ├── console
│   └── setup
├── buffalo-logs.gemspec
├── CODE_OF_CONDUCT.md
├── Gemfile
├── Gemfile.lock
├── lib
│   └── buffalo
│       ├── logs
│       │   └── version.rb
│       └── logs.rb
├── LICENSE.txt
├── Rakefile
├── README.md
└── spec
    ├── buffalo
    │   └── logs_spec.rb
    └── spec_helper.rb

Đây là cấu trúc được tạo ra. Trong bài viết này chúng ta quan tâm đến một số mục sau:

  1. lib/ => Là nơi chúng ta tạo version và là nơi chúng ta viết code xử lý nghiệp vụ.
  2. spec/ => Là nơi chúng ta viết test cho gem.
  3. buffalo-logs.gemspec là nơi chứa các thông tin cơ bản của gem.

buffalo-logs.gemspec

# coding: utf-8
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "buffalo/logs/version"

Gem::Specification.new do |spec|
spec.name          = "buffalo-logs"
spec.version       = Buffalo::Logs::VERSION
spec.authors       = ["oTranQuangTrung"]
spec.email         = ["tran.quang.trung@framgia.com"]

spec.summary       = %q{This gem help you extract log errors to special file}
spec.description   = %q{This gem help you extract log errors to special file}
spec.homepage      = ""
spec.license       = "MIT"
...
end

lib/buffalo/logs/version.rb

module Buffalo
  module Logs
    VERSION = "0.0.3"
  end
end

lib/buffalo/logs.rb Xử lý trong file này thì mình sẽ ghi đè lại Logger để phù hợp với nghiệp vụ của gem.

require "buffalo/logs/version"
require "logger"

module Buffalo
  module Logs
    class Extraction < Logger
      LOG_LEVEL = %i(debug info warn error fatal unknown).freeze
      LOG_LEVEL_SPECIAL = %i(error fatal unknown).freeze

      def initialize path
        @logger_file = {}
        @special_logger_file = {}
        @logger_stdout = {}
        @path = path

        LOG_LEVEL.each do |level|
          @logger_file[level] = Logger.new "#{path}/#{Rails.env}.log"
          @logger_stdout[level] = ActiveSupport::Logger.new STDOUT
        end
        LOG_LEVEL_SPECIAL.each do |level_special|
          @special_logger_file[level_special] = Logger.new "#{path}/#{Rails.env}_special.log"
        end
      end

      LOG_LEVEL.each do |level|
        define_method(level) do |message="", &block|
          @logger_file[level].send level, message, &block
          @logger_stdout[level].send level, message, &block

          if LOG_LEVEL_SPECIAL.include? level
            @special_logger_file[level].send level, message, &block
          end
        end
      end
    end
  end
end

Tiếp theo là phần viết test cho gem Ở trong thư mục spec/ đã được xây dựng thành khung và có môi trường để viết test là rspec. Chúng ta sẽ viết test vào file spec/buffalo/logs_spec.rb. Hiện tại thì mình chưa có viết test cho gem này.

require "spec_helper"

RSpec.describe Buffalo::Logs do
  it "has a version number" do
    expect(Buffalo::Logs::VERSION).not_to be nil
  end

  it "does something useful" do
    expect(true).to eq(true)
  end
end

Release gem

Đầu tiên chúng ta cần tạo tài khoản trên https://rubygems.org Đăng nhập bằng command line.

curl -u your_user_name https://rubygems.org/api/v1/api_key.yaml >~/.gem/credentials; chmod 0600 ~/.gem/credentials
Enter host password for user 'your_user_name':

Tiếp theo ta build gemspec gem build buffalo-logs.gemspec Nếu trong quá trình build có xảy ra lỗi.

ERROR: While executing gem … (URI::InvalidURIError)
bad URI(is not URI?): TODO: Set to ‘http://mygemserver.com’

Thì chúng ta sẽ comment trong file buffalo-logs.gemspec như sau.

  # if spec.respond_to?(:metadata)
  #   spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
  # else
  #   raise "RubyGems 2.0 or newer is required to protect against " 
  #     "public gem pushes."
  # end

Sau đó đẩy project này lên repo github. Chạy lại lệnh gem build buffalo-logs.gemspec

WARNING:  no homepage specified
WARNING:  description and summary are identical
WARNING:  See http://guides.rubygems.org/specification-reference/ for help
Successfully built RubyGem
Name: buffalo-logs
Version: 0.0.3
File: buffalo-logs-0.0.3.gem

Bước cuối cùng chúng ta public gem lên rubygems bằng command với tên phiên bản vừa được tạo ra. gem push buffalo-logs-0.0.3.gem

Conclusion

Vậy là chúng ta đã hoàn thành việc viết một Gem, khá là đơn giản. Hy vọng qua bài này các bạn có thể có hứng thú để viết các opensource thú vị khác. 2 bài viết được tham khảo:

https://viblo.asia/p/step-by-step-tu-xay-dung-ruby-gem-cua-ban-RnB5p1w7KPG https://viblo.asia/p/toi-da-viet-gem-dau-tien-cua-minh-nhu-the-nao-Az45bNeQ5xY

0