Fix code review comments and rename solution

This commit is contained in:
Ilana Kantorov 2017-10-23 15:07:08 +00:00
Родитель 64e0a76d88
Коммит 3086686fce
7 изменённых файлов: 109 добавлений и 87 удалений

Просмотреть файл

@ -1,7 +1,7 @@
PATH PATH
remote: . remote: .
specs: specs:
fluent-plugin-azureactivitylog (0.0.1) fluent-plugin-azuremonitorlog (0.0.2)
azure_mgmt_monitor (~> 0.11.0) azure_mgmt_monitor (~> 0.11.0)
fluentd (>= 0.10.30) fluentd (>= 0.10.30)
@ -68,9 +68,9 @@ PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
fluent-plugin-azureactivitylog! fluent-plugin-azuremonitorlog!
rake (>= 0.9.2) rake (>= 0.9.2)
test-unit (>= 3.1.0) test-unit (>= 3.1.0)
BUNDLED WITH BUNDLED WITH
1.11.2 1.15.4

Просмотреть файл

@ -1,37 +1,46 @@
# fluent-plugin-azureactivitylog, a plugin for [Fluentd](http://fluentd.org) # fluent-plugin-azuremonitorlog, a plugin for [Fluentd](http://fluentd.org)
## Overview ## Overview
***Azure Activity log*** input plugin. ***Azure Monitor log*** input plugin.
This plugin gets the activity logs from Azure Monitor API to fluentd. This plugin gets the monitor activity logs from Azure Monitor API to fluentd.
Installation ## Installation
$ gem install fluent-plugin-azureactivitylog Install from RubyGems:
```
$ gem install fluent-plugin-azuremonitorlog
```
To use this plugin, you need to have Azure Service Principal.<br/>
Create an Azure Service Principal through [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?toc=%2fazure%2fazure-resource-manager%2ftoc.json) or [Azure portal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal).
## Configuration ## Configuration
```config ```config
<source> <source>
@type azureactivitylog @type azuremonitorlog
tag azureactivitylog tag azuremonitorlog
tenant_id [Azure_Tenant_ID] tenant_id [Azure_Tenant_ID]
subscription_id [Azure_Subscription_Id] subscription_id [Azure_Subscription_Id]
client_id [Azure_Client_Id] client_id [Azure_Client_Id]
client_secret [Azure_Client_Secret] client_secret [Azure_Client_Secret]
select_filter [selected fields to query] select [selected fields to query]
event_channels [event channles] (default: Admin, Operation) filter [filter the query query] (default: eventChannels eq 'Admin, Operation')
interval [interval in seconds] (default: 300) interval [interval in seconds] (default: 300)
api_version [api version] (default: 2015-04-01)
</source> </source>
``` ```
Documentation for select and filter can be found [here](https://docs.microsoft.com/en-us/rest/api/monitor/ActivityLogs/List#activitylogs_list_uri_parameters)
### Example for source config ### Example for source config
```config ```config
<source> <source>
@type azureactivitylog @type azuremonitorlog
tag azureactivitylog tag azuremonitorlog
tenant_id [Azure_Tenant_ID] tenant_id [Azure_Tenant_ID]
subscription_id [Azure_Subscription_Id] subscription_id [Azure_Subscription_Id]
client_id [Azure_Client_Id] client_id [Azure_Client_Id]

Просмотреть файл

@ -3,12 +3,12 @@ lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
Gem::Specification.new do |gem| Gem::Specification.new do |gem|
gem.name = "fluent-plugin-azureactivitylog" gem.name = "fluent-plugin-azuremonitorlog"
gem.version = "0.0.1" gem.version = "0.0.1"
gem.authors = ["Ilana Kantorov"] gem.authors = ["Ilana Kantorov"]
gem.email = ["ilanak@microsoft.com"] gem.email = ["ilanak@microsoft.com"]
gem.description = %q{Input plugin for Azure Activity logs.} gem.description = %q{Input plugin for Azure Monitor Activity logs.}
gem.homepage = "https://github.com/..." gem.homepage = "https://github.com/Ilanak/fluent-plugin-azureamonitorlog"
gem.summary = gem.description gem.summary = gem.description
gem.files = `git ls-files`.split($\) gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }

Просмотреть файл

@ -2,8 +2,8 @@ require 'fluent/input'
require 'azure_mgmt_monitor' require 'azure_mgmt_monitor'
require 'uri' require 'uri'
class Fluent::AzureActivityLogInput < Fluent::Input class Fluent::AzureMonitorLogInput < Fluent::Input
Fluent::Plugin.register_input("azureactivitylog", self) Fluent::Plugin.register_input("azuremonitorlog", self)
# To support log_level option implemented by Fluentd v0.10.43 # To support log_level option implemented by Fluentd v0.10.43
unless method_defined?(:log) unless method_defined?(:log)
@ -21,10 +21,10 @@ class Fluent::AzureActivityLogInput < Fluent::Input
config_param :client_id, :string, :default => nil config_param :client_id, :string, :default => nil
config_param :client_secret, :string, :default => nil, :secret => true config_param :client_secret, :string, :default => nil, :secret => true
config_param :select_filter, :string, :default => nil config_param :select, :string, :default => nil
config_param :event_channels, :string, :default => "Admin, Operation" config_param :filter, :string, :default => "eventChannels eq 'Admin, Operation'"
config_param :interval, :integer, :default => 300 config_param :interval, :integer,:default => 300
config_param :api_version, :string, :default => '2015-04-01'
def initialize def initialize
super super
end end
@ -49,11 +49,29 @@ class Fluent::AzureActivityLogInput < Fluent::Input
@watcher.join @watcher.join
end end
def set_query_options(filter, custom_headers)
fail ArgumentError, 'path is nil' if @client.subscription_id.nil?
request_headers = {}
# Set Headers
request_headers['x-ms-client-request-id'] = SecureRandom.uuid
request_headers['accept-language'] = @client.accept_language unless @client.accept_language.nil?
{
middlewares: [[MsRest::RetryPolicyMiddleware, times: 3, retry: 0.02], [:cookie_jar]],
path_params: {'subscriptionId' => @client.subscription_id},
query_params: {'api-version' => @api_version, '$filter' => filter, '$select' => @select},
headers: request_headers.merge(custom_headers || {}),
base_url: @client.base_url
}
end
private private
def watch def watch
while true while true
log.debug "azure activitylog: watch thread starting" log.debug "azure monitorlog: watch thread starting"
output output
sleep @interval sleep @interval
end end
@ -66,40 +84,25 @@ class Fluent::AzureActivityLogInput < Fluent::Input
log.debug "start time: #{start_time}, end time: #{end_time}" log.debug "start time: #{start_time}, end time: #{end_time}"
filter = "eventTimestamp ge '#{start_time}' and eventTimestamp le '#{end_time}'" filter = "eventTimestamp ge '#{start_time}' and eventTimestamp le '#{end_time}'"
if !@event_channels.empty? if !@filter.empty?
filter += " and eventChannels eq '#{@event_channels}'" filter += " and #{@filter}"
end end
activity_logs_promise = get_activity_log_async(filter) monitor_logs_promise = get_monitor_log_async(filter)
activity_logs = activity_logs_promise.value! monitor_logs = monitor_logs_promise.value!
if activity_logs.body.values[0].any? if !monitor_logs.body['value'].nil? and monitor_logs.body['value'].any?
activity_logs.body.values[0].each {|val| monitor_logs.body['value'].each {|val|
router.emit(@tag, Time.now.to_i, val.to_json) router.emit(@tag, Time.now.to_i, val)
} }
else else
log.debug "empty" log.debug "empty"
end end
end end
def get_activity_log_async(filter = nil, custom_headers = nil) def get_monitor_log_async(filter = nil, custom_headers = nil)
fail ArgumentError, 'path is nil' if @client.subscription_id.nil? options = set_query_options(filter, custom_headers)
api_version = '2015-04-01'
request_headers = {}
# Set Headers
request_headers['x-ms-client-request-id'] = SecureRandom.uuid
request_headers['accept-language'] = @client.accept_language unless @client.accept_language.nil?
path_template = '/subscriptions/{subscriptionId}/providers/microsoft.insights/eventtypes/management/values' path_template = '/subscriptions/{subscriptionId}/providers/microsoft.insights/eventtypes/management/values'
options = {
middlewares: [[MsRest::RetryPolicyMiddleware, times: 3, retry: 0.02], [:cookie_jar]],
path_params: {'subscriptionId' => @client.subscription_id},
query_params: {'api-version' => api_version, '$filter' => filter, '$select' => @select_filter},
headers: request_headers.merge(custom_headers || {}),
base_url: @client.base_url
}
promise = @client.make_request_async(:get, path_template, options) promise = @client.make_request_async(:get, path_template, options)
promise = promise.then do |result| promise = promise.then do |result|
@ -108,7 +111,7 @@ class Fluent::AzureActivityLogInput < Fluent::Input
response_content = http_response.body response_content = http_response.body
unless status_code == 200 unless status_code == 200
error_model = JSON.load(response_content) error_model = JSON.load(response_content)
fail MsRestAzure::AzureOperationError.new(result.request, http_response, error_model) log.error(error_model['error']['message'])
end end
result.request_id = http_response['x-ms-request-id'] unless http_response['x-ms-request-id'].nil? result.request_id = http_response['x-ms-request-id'] unless http_response['x-ms-request-id'].nil?
@ -117,7 +120,7 @@ class Fluent::AzureActivityLogInput < Fluent::Input
begin begin
result.body = response_content.to_s.empty? ? nil : JSON.load(response_content) result.body = response_content.to_s.empty? ? nil : JSON.load(response_content)
rescue Exception => e rescue Exception => e
fail MsRest::DeserializationError.new('Error occurred in parsing the response', e.message, e.backtrace, result) log.error("Error occurred in parsing the response")
end end
end end

Просмотреть файл

@ -24,7 +24,7 @@ unless ENV.has_key?("VERBOSE")
$log = nulllogger $log = nulllogger
end end
require "fluent/plugin/in_azureactivitylog" require "fluent/plugin/in_azuremonitorlog"
class Test::Unit::TestCase class Test::Unit::TestCase
end end

Просмотреть файл

@ -1,36 +0,0 @@
require 'helper'
class AzureActivityLogInputTest < Test::Unit::TestCase
def setup
Fluent::Test.setup
end
### for activity log
CONFIG_ACTIVITY_LOG = %[
tag azureactivitylog
tenant_id test_tenant_id
subscription_id test_subscription_id
client_id test_client_id
client_secret test_client_secret
select_filter eventName,id,resourceGroupName,resourceProviderName,operationName,status,eventTimestamp,correlationId
event_channels test_event_channels
interval 300
]
def create_driver_activity_log(conf = CONFIG_ACTIVITY_LOG)
Fluent::Test::InputTestDriver.new(Fluent::AzureActivityLogInput).configure(conf)
end
def test_configure_activity_log
d = create_driver_activity_log
assert_equal 'azureactivitylog', d.instance.tag
assert_equal 'test_tenant_id', d.instance.tenant_id
assert_equal 'test_subscription_id', d.instance.subscription_id
assert_equal 'test_client_id', d.instance.client_id
assert_equal 'test_client_secret', d.instance.client_secret
assert_equal 'eventName,id,resourceGroupName,resourceProviderName,operationName,status,eventTimestamp,correlationId', d.instance.select_filter
assert_equal 'test_event_channels', d.instance.event_channels
assert_equal 300, d.instance.interval
end
end

Просмотреть файл

@ -0,0 +1,46 @@
require 'helper'
class AzureMonitorLogInputTest < Test::Unit::TestCase
def setup
Fluent::Test.setup
end
### for monitor log
CONFIG_MONITOR_LOG = %[
tag azuremonitorlog
tenant_id test_tenant_id
subscription_id test_subscription_id
client_id test_client_id
client_secret test_client_secret
select eventName,id,resourceGroupName,resourceProviderName,operationName,status,eventTimestamp,correlationId
filter eventChannels eq 'Admin, Operation'
interval 300
api_version 2015-04-01
]
def create_driver_monitor_log(conf = CONFIG_MONITOR_LOG)
Fluent::Test::InputTestDriver.new(Fluent::AzureMonitorLogInput).configure(conf)
end
def test_configure_monitor_log
d = create_driver_monitor_log
assert_equal 'azuremonitorlog', d.instance.tag
assert_equal 'test_tenant_id', d.instance.tenant_id
assert_equal 'test_subscription_id', d.instance.subscription_id
assert_equal 'test_client_id', d.instance.client_id
assert_equal 'test_client_secret', d.instance.client_secret
assert_equal 'eventName,id,resourceGroupName,resourceProviderName,operationName,status,eventTimestamp,correlationId', d.instance.select
assert_equal 'eventChannels eq \'Admin, Operation\'', d.instance.filter
assert_equal 300, d.instance.interval
assert_equal '2015-04-01', d.instance.api_version
end
def test_set_query_options
d = create_driver_monitor_log
query_options = d.instance.set_query_options(d.instance.filter, {})
assert_equal '2015-04-01', query_options[:query_params]['api-version']
assert_equal 'eventChannels eq \'Admin, Operation\'', query_options[:query_params]['$filter']
assert_equal 'eventName,id,resourceGroupName,resourceProviderName,operationName,status,eventTimestamp,correlationId', query_options[:query_params]['$select']
end
end