logstash-output-application_insights 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/CONTRIBUTORS +9 -0
- data/DEVELOPER.md +0 -0
- data/Gemfile +26 -0
- data/LICENSE +17 -0
- data/README.md +495 -0
- data/Rakefile +22 -0
- data/lib/logstash/outputs/application_insights.rb +393 -0
- data/lib/logstash/outputs/application_insights/blob.rb +923 -0
- data/lib/logstash/outputs/application_insights/block.rb +118 -0
- data/lib/logstash/outputs/application_insights/channel.rb +259 -0
- data/lib/logstash/outputs/application_insights/channels.rb +142 -0
- data/lib/logstash/outputs/application_insights/client.rb +110 -0
- data/lib/logstash/outputs/application_insights/clients.rb +113 -0
- data/lib/logstash/outputs/application_insights/config.rb +341 -0
- data/lib/logstash/outputs/application_insights/constants.rb +208 -0
- data/lib/logstash/outputs/application_insights/exceptions.rb +55 -0
- data/lib/logstash/outputs/application_insights/flow_control.rb +80 -0
- data/lib/logstash/outputs/application_insights/multi_io_logger.rb +69 -0
- data/lib/logstash/outputs/application_insights/shutdown.rb +96 -0
- data/lib/logstash/outputs/application_insights/state.rb +89 -0
- data/lib/logstash/outputs/application_insights/storage_cleanup.rb +214 -0
- data/lib/logstash/outputs/application_insights/sub_channel.rb +75 -0
- data/lib/logstash/outputs/application_insights/telemetry.rb +99 -0
- data/lib/logstash/outputs/application_insights/timer.rb +90 -0
- data/lib/logstash/outputs/application_insights/utils.rb +139 -0
- data/lib/logstash/outputs/application_insights/version.rb +24 -0
- data/logstash-output-application-insights.gemspec +50 -0
- data/spec/outputs/application_insights_spec.rb +42 -0
- metadata +151 -0
@@ -0,0 +1,208 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------------
|
4
|
+
# Logstash Output Application Insights
|
5
|
+
#
|
6
|
+
# Copyright (c) Microsoft Corporation
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the License);
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
#
|
18
|
+
# See the Apache Version 2.0 License for specific language governing
|
19
|
+
# permissions and limitations under the License.
|
20
|
+
# ----------------------------------------------------------------------------------
|
21
|
+
|
22
|
+
class LogStash::Outputs::Application_insights
|
23
|
+
|
24
|
+
def default_configuration
|
25
|
+
{
|
26
|
+
:notification_version => @notification_version || DEFAULT_NOTIFICATION_VERSION,
|
27
|
+
:event_separator => @event_separator || DEFAULT_EVENT_SEPARATOR,
|
28
|
+
|
29
|
+
:notification_endpoint => @notification_endpoint || DEFAULT_NOTIFICATION_ENDPOINT,
|
30
|
+
:azure_storage_blob_prefix => @azure_storage_blob_prefix || DEFAULT_AZURE_STORAGE_BLOB_PREFIX || Utils.to_storage_name( Socket.gethostname.strip ) || "",
|
31
|
+
:azure_storage_container_prefix => @azure_storage_container_prefix || DEFAULT_AZURE_STORAGE_CONTAINER_PREFIX || Utils.to_storage_name( Socket.gethostname.strip ) || "",
|
32
|
+
:azure_storage_table_prefix => @azure_storage_table_prefix || DEFAULT_AZURE_STORAGE_TABLE_PREFIX || Utils.to_storage_name( Socket.gethostname.strip ) || "",
|
33
|
+
:storage_account_name_key => @storage_account_name_key || [ ],
|
34
|
+
:disable_notification => @disable_notification || DEFAULT_DISABLE_NOTIFICATION,
|
35
|
+
:disable_blob_upload => @disable_blob_upload || DEFAULT_DISABLE_BLOB_UPLOAD,
|
36
|
+
:stop_on_unknown_io_errors => @stop_on_unknown_io_errors || DEFAULT_STOP_ON_UNKNOWN_IO_ERRORS,
|
37
|
+
:delete_not_notified_blobs => @delete_not_notified_blobs || DEFAULT_DELETE_NOT_NOTIFIED_BLOBS,
|
38
|
+
:save_notified_blobs_records => @save_notified_blobs_records || DEFAULT_SAVE_NOTIFIED_BLOBS_RECORDS,
|
39
|
+
:disable_telemetry => @disable_telemetry || DEFAULT_DISABLE_TELEMETRY,
|
40
|
+
:disable_cleanup => @disable_cleanup || DEFAULT_DISABLE_CLEANUP,
|
41
|
+
:blob_max_bytesize => @blob_max_bytesize || DEFAULT_BLOB_MAX_BYTESIZE,
|
42
|
+
:blob_max_events => @blob_max_events || DEFAULT_BLOB_MAX_EVENTS,
|
43
|
+
:blob_retention_time => @blob_retention_time || DEFAULT_BLOB_RETENTION_TIME,
|
44
|
+
:blob_access_expiry_time => @blob_access_expiry_time || DEFAULT_BLOB_ACCESS_EXPIRY_TIME,
|
45
|
+
|
46
|
+
:resurrect_delay => @resurrect_delay || DEFAULT_STORAGE_RESURRECT_DELAY,
|
47
|
+
:io_retry_delay => @io_retry_delay || DEFAULT_IO_RETRY_DELAY,
|
48
|
+
:io_max_retries => @io_max_retries || DEFAULT_IO_MAX_RETRIES,
|
49
|
+
|
50
|
+
:logger_level => @logger_level || DEFAULT_LOG_LEVEL,
|
51
|
+
:logger_files => @logger_files || DEFAULT_LOGGER_FILES,
|
52
|
+
:logger_progname => @logger_progname || DEFAULT_LOGGER_PROGNAME,
|
53
|
+
:logger_shift_size => @logger_shift_size || DEFAULT_LOGGER_SHIFT_SIZE,
|
54
|
+
:logger_shift_age => @logger_shift_age || DEFAULT_LOGGER_SHIFT_AGE,
|
55
|
+
|
56
|
+
:flow_control_suspend_bytes => @flow_control_suspend_bytes || DEFAULT_FLOW_CONTROL_SUSPEND_BYTES,
|
57
|
+
:flow_control_resume_bytes => @flow_control_resume_bytes || DEFAULT_FLOW_CONTROL_RESUME_BYTES,
|
58
|
+
:flow_control_delay => @flow_control_delay || DEFAULT_FLOW_CONTROL_DELAY,
|
59
|
+
|
60
|
+
:ca_file => @ca_file || "",
|
61
|
+
|
62
|
+
:tables => @tables || { },
|
63
|
+
:table_id => @table_id || DEFAULT_TABLE_ID,
|
64
|
+
:intrumentation_key => @intrumentation_key || DEFAULT_INSTRUMENTATION_KEY,
|
65
|
+
:table_columns => @table_columns,
|
66
|
+
:case_insensitive_columns => @case_insensitive_columns || DEFAULT_CASE_INSENSITIVE,
|
67
|
+
:serialized_event_field => @serialized_event_field,
|
68
|
+
:blob_max_delay => @blob_max_delay || DEFAULT_BLOB_MAX_DELAY,
|
69
|
+
:blob_serialization => @blob_serialization || DEFAULT_BLOB_SERIALIZATION,
|
70
|
+
:csv_separator => @csv_separator || DEFAULT_CSV_SEPARATOR,
|
71
|
+
:csv_default_value => @csv_default_value || DEFAULT_CSV_DEFAULT_VALUE,
|
72
|
+
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
BOOLEAN_PROPERTIES = [ :disable_notification, :disable_blob_upload,
|
77
|
+
:stop_on_unknown_io_errors, :disable_telemetry,
|
78
|
+
:disable_cleanup, :delete_not_notified_blobs,
|
79
|
+
:save_notified_blobs_records, :case_insensitive_columns,
|
80
|
+
:table_columns, :serialized_event_field ]
|
81
|
+
|
82
|
+
GUID_NULL = "00000000-0000-0000-0000-000000000000"
|
83
|
+
INSTRUMENTATION_KEY_TEMPLATE = "KKKKKKKK-KKKK-KKKK-KKKK-KKKKKKKKKKKK"
|
84
|
+
TABLE_ID_TEMPLATE = "SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS"
|
85
|
+
|
86
|
+
# notification payload constants
|
87
|
+
REQUEST_NAME = "Microsoft.ApplicationInsights.OpenSchema"
|
88
|
+
BASE_DATA_REQUIRED_VERSION = "2"
|
89
|
+
DATA_BASE_TYPE = "OpenSchemaData"
|
90
|
+
|
91
|
+
# logger constants
|
92
|
+
LOGGER_LEVEL_MAP = {:DEBUG => Logger::DEBUG, :INFO => Logger::INFO, :WARN => Logger::WARN, :ERROR => Logger::ERROR, :FATAL => Logger::FATAL, :UNKNOWN => Logger::UNKNOWN}
|
93
|
+
|
94
|
+
BLOB_BLOCK_MAX_BYTESIZE = 4 * 1024 * 1024 # in bytes - 4 Mega bytes - blob limitation
|
95
|
+
|
96
|
+
BLOB_MAX_BLOCKS = 50000 # in blocks - 50,0000 blocks - blob limitation
|
97
|
+
|
98
|
+
MIN_BLOB_MAX_BYTESIZE = BLOB_BLOCK_MAX_BYTESIZE # BLOB_BLOCK_MAX_BYTESIZE
|
99
|
+
MAX_BLOB_MAX_BYTESIZE = BLOB_MAX_BLOCKS * BLOB_BLOCK_MAX_BYTESIZE # 192 Giga bytes
|
100
|
+
|
101
|
+
MIN_BLOB_MAX_EVENTS = 1 # 256 Kilo events
|
102
|
+
MAX_BLOB_MAX_EVENTS = 0 # No Limit
|
103
|
+
|
104
|
+
MIN_BLOB_MAX_DELAY = 1 # in seconds - one second
|
105
|
+
MAX_BLOB_MAX_DELAY = 24 * 3600 # in seconds - one day
|
106
|
+
|
107
|
+
MIN_BLOB_RETENTION_TIME = 60 # in seconds - one minute
|
108
|
+
MAX_BLOB_RETENTION_TIME = 60 * 60 * 24 * 365 # in seconds - one year
|
109
|
+
|
110
|
+
MIN_BLOB_ACCESS_EXPIRY_TIME = 60 # in seconds - one minute
|
111
|
+
MAX_BLOB_ACCESS_EXPIRY_TIME = 60 * 60 * 24 * 365 # in seconds - one year
|
112
|
+
|
113
|
+
MIN_STORAGE_RESURRECT_DELAY = 1 # in seconds - one second
|
114
|
+
MAX_STORAGE_RESURRECT_DELAY = 3600 # in seconds - one hour
|
115
|
+
|
116
|
+
MIN_LOGGER_SHIFT_SIZE = 1024 # in bytes - 1 Kilo bytes
|
117
|
+
MAX_LOGGER_SHIFT_SIZE = 1 * 1024 * 1024 * 1024 # in bytes - 1 Giga bytes
|
118
|
+
|
119
|
+
MIN_LOGGER_SHIFT_AGE = 0 # in retension version - no
|
120
|
+
MAX_LOGGER_SHIFT_AGE = 100000 # in retension version - almost limitless
|
121
|
+
|
122
|
+
MIN_IO_RETRY_DELAY = 0 # in seconds
|
123
|
+
MAX_IO_RETRY_DELAY = 300 # in seconds - 5 minutes
|
124
|
+
|
125
|
+
MIN_IO_MAX_RETRIES = 0
|
126
|
+
MAX_IO_MAX_RETRIES = 3
|
127
|
+
|
128
|
+
|
129
|
+
MIN_FLOW_CONTROL_SUSPEND_BYTES = 0 # in bytes,
|
130
|
+
MAX_FLOW_CONTROL_SUSPEND_BYTES = 0 # in bytes, 0 means no upper limit
|
131
|
+
|
132
|
+
MIN_FLOW_CONTROL_RESUME_BYTES = 0 # in bytes
|
133
|
+
MAX_FLOW_CONTROL_RESUME_BYTES = 0 # in bytes, 0 means no upper limit
|
134
|
+
|
135
|
+
MIN_FLOW_CONTROL_DELAY = 0.1 # in seconds, 1 seconds, can be less than 1 seconds, like 0.5, 0.1
|
136
|
+
MAX_FLOW_CONTROL_DELAY = 0 # in seconds, 1 seconds, can be less than 1 seconds, like 0.5, 0.1
|
137
|
+
|
138
|
+
METADATA_FIELD_INSTRUMENTATION_KEY = "[@metadata]intrumentation_key"
|
139
|
+
METADATA_FIELD_TABLE_ID = "[@metadata]table_id"
|
140
|
+
FIELD_INSTRUMENTATION_KEY = "intrumentation_key"
|
141
|
+
FIELD_TABLE_ID = "table_id"
|
142
|
+
|
143
|
+
STATE_TABLE_NAME = "BlobsState"
|
144
|
+
|
145
|
+
AZURE_STORAGE_CONTAINER_LOGSTASH_PREFIX = "logstash" # lower case only, dash allowed
|
146
|
+
AZURE_STORAGE_BLOB_LOGSTASH_PREFIX = "logstash"
|
147
|
+
AZURE_STORAGE_TABLE_LOGSTASH_PREFIX = "Logstash" # case sensitive, no dash
|
148
|
+
|
149
|
+
AZURE_STORAGE_ORPHAN_BLOBS_CONTAINER_NAME = "orphan-blobs"
|
150
|
+
AZURE_STORAGE_NOTIFIED_BLOBS_TABLE_NAME = "orphan-blobs"
|
151
|
+
|
152
|
+
COLUMN_PROPERTY_NAME = "name"
|
153
|
+
COLUMN_PROPERTY_TYPE = "type"
|
154
|
+
COLUMN_PROPERTY_DEFAULT = "default"
|
155
|
+
VALID_FIELDS_MAP_TYPES = [ "string", "hash", "array", "number", "json", "boolean", "float", "integer", "dynamic", "datetime", "object" ]
|
156
|
+
|
157
|
+
VALID_LOGGER_SHIFT_AGES = [ "daily", "weekly", "monthly" ]
|
158
|
+
|
159
|
+
EXT_EVENT_FORMAT_JSON = "json"
|
160
|
+
EXT_EVENT_FORMAT_CSV = "csv"
|
161
|
+
VALID_EXT_EVENT_FORMAT = [EXT_EVENT_FORMAT_JSON, EXT_EVENT_FORMAT_CSV ]
|
162
|
+
|
163
|
+
DEFAULT_INSTRUMENTATION_KEY = GUID_NULL
|
164
|
+
DEFAULT_TABLE_ID = GUID_NULL
|
165
|
+
DEFAULT_EVENT_SEPARATOR = "\r\n"
|
166
|
+
DEFAULT_CSV_SEPARATOR = ","
|
167
|
+
DEFAULT_CSV_DEFAULT_VALUE = ""
|
168
|
+
DEFAULT_AZURE_STORAGE_BLOB_PREFIX = nil
|
169
|
+
DEFAULT_AZURE_STORAGE_CONTAINER_PREFIX = nil
|
170
|
+
DEFAULT_AZURE_STORAGE_TABLE_PREFIX = nil
|
171
|
+
DEFAULT_JSON_EXT = EXT_EVENT_FORMAT_JSON
|
172
|
+
DEFAULT_CSV_EXT = EXT_EVENT_FORMAT_CSV
|
173
|
+
|
174
|
+
|
175
|
+
DEFAULT_BLOB_SERIALIZATION = EXT_EVENT_FORMAT_JSON
|
176
|
+
|
177
|
+
DEFAULT_BLOB_MAX_BYTESIZE = 1 * 1024 * 1024 * 1024
|
178
|
+
DEFAULT_BLOB_MAX_EVENTS = 256 * 1024 # 256 Kilo events
|
179
|
+
|
180
|
+
DEFAULT_BLOB_MAX_DELAY = 60 # in seconds
|
181
|
+
DEFAULT_BLOB_RETENTION_TIME = 60 * 60 * 24 * 7 # in seconds - one week
|
182
|
+
DEFAULT_BLOB_ACCESS_EXPIRY_TIME = 60 * 60 * 24 * 1 # in seconds - one day
|
183
|
+
DEFAULT_STORAGE_RESURRECT_DELAY = 10
|
184
|
+
DEFAULT_NOTIFICATION_ENDPOINT = "https://dc.services.visualstudio.com/v2/track"
|
185
|
+
DEFAULT_NOTIFICATION_VERSION = 1
|
186
|
+
DEFAULT_DISABLE_NOTIFICATION = false
|
187
|
+
DEFAULT_DISABLE_BLOB_UPLOAD = false
|
188
|
+
DEFAULT_STOP_ON_UNKNOWN_IO_ERRORS = false
|
189
|
+
DEFAULT_DISABLE_TELEMETRY = false
|
190
|
+
DEFAULT_DISABLE_CLEANUP = false
|
191
|
+
DEFAULT_DELETE_NOT_NOTIFIED_BLOBS = false
|
192
|
+
DEFAULT_SAVE_NOTIFIED_BLOBS_RECORDS = false
|
193
|
+
|
194
|
+
DEFAULT_CASE_INSENSITIVE = false
|
195
|
+
|
196
|
+
DEFAULT_LOGGER_FILES = [ "logstash-output-application-insights.log" ]
|
197
|
+
DEFAULT_LOG_LEVEL = "INFO"
|
198
|
+
DEFAULT_LOGGER_PROGNAME = "AI"
|
199
|
+
DEFAULT_LOGGER_SHIFT_AGE = "daily" # daily back retension
|
200
|
+
DEFAULT_LOGGER_SHIFT_SIZE = 1024 * 1024 # in bytes - one Mega bytes
|
201
|
+
|
202
|
+
DEFAULT_IO_RETRY_DELAY = 10 # in seconds
|
203
|
+
DEFAULT_IO_MAX_RETRIES = 2
|
204
|
+
|
205
|
+
DEFAULT_FLOW_CONTROL_SUSPEND_BYTES = 50 *1024 * 1024 # high water mark, -in bytes, based on my laptop experience, without Java to break to NO MEMORY error
|
206
|
+
DEFAULT_FLOW_CONTROL_RESUME_BYTES = 40 *1024 * 1024 # low water mark,
|
207
|
+
DEFAULT_FLOW_CONTROL_DELAY = 1 # in seconds, 1 seconds, can be less than 1 seconds, like 0.5, 0.1
|
208
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------------
|
4
|
+
# Logstash Output Application Insights
|
5
|
+
#
|
6
|
+
# Copyright (c) Microsoft Corporation
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the License);
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
#
|
18
|
+
# See the Apache Version 2.0 License for specific language governing
|
19
|
+
# permissions and limitations under the License.
|
20
|
+
# ----------------------------------------------------------------------------------
|
21
|
+
|
22
|
+
class LogStash::Outputs::Application_insights
|
23
|
+
|
24
|
+
# exception that are handled internally and do NOT cause process to end
|
25
|
+
class BlockOverflowError < StandardError
|
26
|
+
end
|
27
|
+
|
28
|
+
class BlockTooSmallError < StandardError
|
29
|
+
end
|
30
|
+
|
31
|
+
class NoChannelError < StandardError
|
32
|
+
end
|
33
|
+
|
34
|
+
class ChannelExistError < StandardError
|
35
|
+
end
|
36
|
+
|
37
|
+
class StorageAccountsOffError < StandardError
|
38
|
+
end
|
39
|
+
|
40
|
+
class UploadRetryError < StandardError
|
41
|
+
end
|
42
|
+
|
43
|
+
class NotRecoverableError < StandardError
|
44
|
+
end
|
45
|
+
|
46
|
+
# exception that cause process to end
|
47
|
+
# LogStash::ConfigurationError, "ssl_truststore_location must be set when SSL is enabled"
|
48
|
+
# class ConfigurationError < StandardError
|
49
|
+
class ConfigurationError < LogStash::ConfigurationError
|
50
|
+
end
|
51
|
+
|
52
|
+
class UnexpectedBranchError < StandardError
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------------
|
4
|
+
# Logstash Output Application Insights
|
5
|
+
#
|
6
|
+
# Copyright (c) Microsoft Corporation
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the License);
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
#
|
18
|
+
# See the Apache Version 2.0 License for specific language governing
|
19
|
+
# permissions and limitations under the License.
|
20
|
+
# ----------------------------------------------------------------------------------
|
21
|
+
|
22
|
+
class LogStash::Outputs::Application_insights
|
23
|
+
class Flow_control
|
24
|
+
|
25
|
+
public
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
configuration = Config.current
|
29
|
+
|
30
|
+
@logger_progname = configuration[:logger_progname]
|
31
|
+
@logger = configuration[:logger]
|
32
|
+
|
33
|
+
@flow_control_suspend_bytes = configuration[:flow_control_suspend_bytes]
|
34
|
+
@flow_control_resume_bytes = configuration[:flow_control_resume_bytes]
|
35
|
+
@flow_control_delay = configuration[:flow_control_delay]
|
36
|
+
|
37
|
+
@flow_control_semaphore = Mutex.new
|
38
|
+
|
39
|
+
@state = State.instance
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def pass_or_wait
|
44
|
+
bytes_in_memory = @state.bytes_in_memory
|
45
|
+
return if bytes_in_memory <= @flow_control_resume_bytes
|
46
|
+
|
47
|
+
@flow_control_semaphore.synchronize {
|
48
|
+
bytes_in_memory = @state.bytes_in_memory
|
49
|
+
if bytes_in_memory > @flow_control_suspend_bytes
|
50
|
+
display_msg( "suspend receiving event, memory above #{@flow_control_suspend_bytes} bytes, wait till memory below #{@flow_control_resume_bytes} bytes" )
|
51
|
+
loop do
|
52
|
+
GC.start
|
53
|
+
sleep( @flow_control_delay )
|
54
|
+
bytes_in_memory = @state.bytes_in_memory
|
55
|
+
break if bytes_in_memory <= @flow_control_resume_bytes
|
56
|
+
display_msg( "continue to suspend receiving event, memory level #{bytes_in_memory} bytes, wait till memory below #{@flow_control_resume_bytes} bytes " )
|
57
|
+
end
|
58
|
+
display_msg( "resume receiving event, memory level #{bytes_in_memory}, below #{@flow_control_resume_bytes} bytes" )
|
59
|
+
end
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def display_msg ( msg )
|
66
|
+
puts "+++ #{@logger_progname} #{msg}"
|
67
|
+
# @logger.info { "#{msg}" }
|
68
|
+
end
|
69
|
+
|
70
|
+
public
|
71
|
+
|
72
|
+
@@instance = Flow_control.new
|
73
|
+
|
74
|
+
def self.instance
|
75
|
+
@@instance
|
76
|
+
end
|
77
|
+
|
78
|
+
private_class_method :new
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------------
|
4
|
+
# Logstash Output Application Insights
|
5
|
+
#
|
6
|
+
# Copyright (c) Microsoft Corporation
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the License);
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
#
|
18
|
+
# See the Apache Version 2.0 License for specific language governing
|
19
|
+
# permissions and limitations under the License.
|
20
|
+
# ----------------------------------------------------------------------------------
|
21
|
+
|
22
|
+
class LogStash::Outputs::Application_insights
|
23
|
+
class Multi_io_logger
|
24
|
+
|
25
|
+
def self.config ( configuration )
|
26
|
+
files = configuration[:logger_files].dup
|
27
|
+
level = configuration[:logger_level]
|
28
|
+
progname = configuration[:logger_progname]
|
29
|
+
shift_size = configuration[:logger_shift_size]
|
30
|
+
shift_age = configuration[:logger_shift_age]
|
31
|
+
|
32
|
+
files.rotate! if files.length > 1 && [ :stdout, :stderr ].include?( files[0][0] )
|
33
|
+
(name, file) = files.shift || [ :stdout, STDOUT ]
|
34
|
+
if [ :stdout, :stderr ].include?( name )
|
35
|
+
logger = Logger.new( file )
|
36
|
+
else
|
37
|
+
begin
|
38
|
+
file_renamed = File.rename( name, "#{name}.20160714" )
|
39
|
+
file_renamed = File.rename( "#{name}.20160714", name )
|
40
|
+
logger = Logger.new( name, shift_age, shift_size )
|
41
|
+
rescue
|
42
|
+
puts "--- logger do not support log shifting on this OS"
|
43
|
+
logger = Logger.new( name )
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
unless files.empty?
|
48
|
+
@@targets = files
|
49
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
50
|
+
formatted_msg = "#{severity[0]}, [#{datetime.utc.iso8601(6)} ##{Process.pid}] #{severity} -- #{progname}: #{msg}#{$/}"
|
51
|
+
begin
|
52
|
+
@@targets.each do |name, t|
|
53
|
+
t.write( formatted_msg )
|
54
|
+
t.flush
|
55
|
+
end
|
56
|
+
rescue # ignore errors
|
57
|
+
end
|
58
|
+
formatted_msg
|
59
|
+
end
|
60
|
+
end
|
61
|
+
logger.progname = progname
|
62
|
+
logger.level = ( level unless configuration[:logger_files].empty? ) || Logger::UNKNOWN
|
63
|
+
configuration[:logger] = logger
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------------
|
4
|
+
# Logstash Output Application Insights
|
5
|
+
#
|
6
|
+
# Copyright (c) Microsoft Corporation
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the License);
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
#
|
18
|
+
# See the Apache Version 2.0 License for specific language governing
|
19
|
+
# permissions and limitations under the License.
|
20
|
+
# ----------------------------------------------------------------------------------
|
21
|
+
|
22
|
+
class LogStash::Outputs::Application_insights
|
23
|
+
class Shutdown
|
24
|
+
|
25
|
+
public
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
configuration = Config.current
|
29
|
+
|
30
|
+
@logger_progname = configuration[:logger_progname]
|
31
|
+
@logger = configuration[:logger]
|
32
|
+
|
33
|
+
@state = State.instance
|
34
|
+
@channels = Channels.instance
|
35
|
+
end
|
36
|
+
|
37
|
+
def submit
|
38
|
+
display_msg( "start graceful shutdown, flush all events" )
|
39
|
+
|
40
|
+
# wait for all uploads to finish
|
41
|
+
start_bytes_in_memory = @state.bytes_in_memory
|
42
|
+
bytes_in_memory = start_bytes_in_memory
|
43
|
+
while bytes_in_memory > 0 do
|
44
|
+
sleep( 1 )
|
45
|
+
bytes_in_memory = @state.bytes_in_memory
|
46
|
+
percent = 100 * (1 - ( bytes_in_memory.to_f / start_bytes_in_memory ) )
|
47
|
+
display_msg( "#{percent.to_i}% events were uploaded to Azure storage" ) if percent < 100.0
|
48
|
+
end
|
49
|
+
display_msg( "all events were uploaded to Azure storage" )
|
50
|
+
|
51
|
+
Blob.close
|
52
|
+
@channels.close
|
53
|
+
|
54
|
+
# wait for all uploads to commit
|
55
|
+
start_pending_commits = @state.pending_commits
|
56
|
+
pending_commits = start_pending_commits
|
57
|
+
while pending_commits > 0 do
|
58
|
+
sleep( 1 )
|
59
|
+
pending_commits = @state.pending_commits
|
60
|
+
percent = 100 * (1 - ( pending_commits.to_f / start_pending_commits ) )
|
61
|
+
display_msg( "#{percent.to_i}% events were commited to Azure storage" ) if percent < 100.0
|
62
|
+
end
|
63
|
+
display_msg( "all events were commited to Azure storage" )
|
64
|
+
|
65
|
+
# wait for all blobs to be notified
|
66
|
+
start_pending_notifications = @state.pending_notifications
|
67
|
+
pending_notifications = start_pending_notifications
|
68
|
+
while pending_notifications > 0 do
|
69
|
+
sleep( 1 )
|
70
|
+
pending_notifications = @state.pending_notifications
|
71
|
+
percent = 100 * (1 - ( pending_notifications.to_f / start_pending_notifications ) )
|
72
|
+
display_msg( "#{percent.to_i}% events were notified to Application Insights Analytics" ) if percent < 100.0
|
73
|
+
end
|
74
|
+
|
75
|
+
# done
|
76
|
+
display_msg( "all events were notified to Application Insights Analytics" )
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def display_msg ( msg )
|
82
|
+
puts "+++ #{@logger_progname} #{msg}"
|
83
|
+
# @logger.info { "#{msg}" }
|
84
|
+
end
|
85
|
+
|
86
|
+
public
|
87
|
+
|
88
|
+
@@instance = Shutdown.new
|
89
|
+
|
90
|
+
def self.instance
|
91
|
+
@@instance
|
92
|
+
end
|
93
|
+
|
94
|
+
private_class_method :new
|
95
|
+
end
|
96
|
+
end
|