fluent-plugin-google-cloud 0.6.4 → 0.6.5.pre.1
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 +4 -4
- data/Gemfile.lock +21 -21
- data/fluent-plugin-google-cloud.gemspec +5 -4
- data/lib/fluent/plugin/out_google_cloud.rb +812 -360
- data/test/plugin/base_test.rb +389 -77
- data/test/plugin/constants.rb +163 -0
- metadata +31 -11
data/test/plugin/base_test.rb
CHANGED
@@ -100,7 +100,7 @@ module BaseTest
|
|
100
100
|
assert_equal PROJECT_ID, d.instance.project_id
|
101
101
|
assert_equal ZONE, d.instance.zone
|
102
102
|
assert_equal VM_ID, d.instance.vm_id
|
103
|
-
assert_equal
|
103
|
+
assert_equal COMPUTE_CONSTANTS[:resource_type], d.instance.resource.type
|
104
104
|
end
|
105
105
|
|
106
106
|
def test_managed_vm_metadata_loading
|
@@ -111,9 +111,11 @@ module BaseTest
|
|
111
111
|
assert_equal PROJECT_ID, d.instance.project_id
|
112
112
|
assert_equal ZONE, d.instance.zone
|
113
113
|
assert_equal VM_ID, d.instance.vm_id
|
114
|
-
assert_equal
|
115
|
-
assert_equal MANAGED_VM_BACKEND_NAME,
|
116
|
-
|
114
|
+
assert_equal APPENGINE_CONSTANTS[:resource_type], d.instance.resource.type
|
115
|
+
assert_equal MANAGED_VM_BACKEND_NAME,
|
116
|
+
d.instance.resource.labels['module_id']
|
117
|
+
assert_equal MANAGED_VM_BACKEND_VERSION,
|
118
|
+
d.instance.resource.labels['version_id']
|
117
119
|
end
|
118
120
|
|
119
121
|
def test_gce_metadata_does_not_load_when_use_metadata_service_is_false
|
@@ -123,7 +125,7 @@ module BaseTest
|
|
123
125
|
assert_equal CUSTOM_PROJECT_ID, d.instance.project_id
|
124
126
|
assert_equal CUSTOM_ZONE, d.instance.zone
|
125
127
|
assert_equal CUSTOM_VM_ID, d.instance.vm_id
|
126
|
-
assert_equal
|
128
|
+
assert_equal COMPUTE_CONSTANTS[:resource_type], d.instance.resource.type
|
127
129
|
end
|
128
130
|
|
129
131
|
def test_gce_used_when_detect_subservice_is_false
|
@@ -157,8 +159,6 @@ module BaseTest
|
|
157
159
|
assert_equal parts[1], d.instance.project_id, "Index #{index} failed."
|
158
160
|
assert_equal parts[2], d.instance.zone, "Index #{index} failed."
|
159
161
|
assert_equal parts[3], d.instance.vm_id, "Index #{index} failed."
|
160
|
-
assert_equal false, d.instance.running_on_managed_vm,
|
161
|
-
"Index #{index} failed."
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
@@ -702,78 +702,17 @@ module BaseTest
|
|
702
702
|
end
|
703
703
|
end
|
704
704
|
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
d.emit(container_log_entry_with_metadata(log_entry(0)))
|
711
|
-
d.run
|
712
|
-
end
|
713
|
-
verify_log_entries(1, CONTAINER_FROM_METADATA_PARAMS) do |entry|
|
714
|
-
assert_equal CONTAINER_SECONDS_EPOCH, entry['timestamp']['seconds'], entry
|
715
|
-
assert_equal CONTAINER_NANOS, entry['timestamp']['nanos'], entry
|
716
|
-
assert_equal CONTAINER_SEVERITY, entry['severity'], entry
|
717
|
-
end
|
718
|
-
end
|
719
|
-
|
720
|
-
def test_multiple_container_logs_metadata_from_plugin
|
721
|
-
setup_gce_metadata_stubs
|
722
|
-
setup_container_metadata_stubs
|
723
|
-
[2, 3, 5, 11, 50].each do |n|
|
724
|
-
@logs_sent = []
|
725
|
-
setup_logging_stubs do
|
726
|
-
d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
|
727
|
-
# The test driver doesn't clear its buffer of entries after running, so
|
728
|
-
# do it manually here.
|
729
|
-
d.instance_variable_get('@entries').clear
|
730
|
-
n.times { |i| d.emit(container_log_entry_with_metadata(log_entry(i))) }
|
731
|
-
d.run
|
732
|
-
end
|
733
|
-
verify_log_entries(n, CONTAINER_FROM_METADATA_PARAMS) do |entry|
|
734
|
-
assert_equal CONTAINER_SECONDS_EPOCH, entry['timestamp']['seconds'],
|
735
|
-
entry
|
736
|
-
assert_equal CONTAINER_NANOS, entry['timestamp']['nanos'], entry
|
737
|
-
assert_equal CONTAINER_SEVERITY, entry['severity'], entry
|
738
|
-
end
|
739
|
-
end
|
705
|
+
# Test container logs when metadata is extracted from the 'kubernetes' field
|
706
|
+
# in the log record.
|
707
|
+
def test_container_logs_metadata_from_record
|
708
|
+
verify_container_logs(method(:container_log_entry_with_metadata),
|
709
|
+
CONTAINER_FROM_METADATA_PARAMS)
|
740
710
|
end
|
741
711
|
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
@logs_sent = []
|
747
|
-
setup_logging_stubs do
|
748
|
-
d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
|
749
|
-
# The test driver doesn't clear its buffer of entries after running, so
|
750
|
-
# do it manually here.
|
751
|
-
d.instance_variable_get('@entries').clear
|
752
|
-
n.times { |i| d.emit(container_log_entry(log_entry(i))) }
|
753
|
-
d.run
|
754
|
-
end
|
755
|
-
verify_log_entries(n, CONTAINER_FROM_TAG_PARAMS) do |entry|
|
756
|
-
assert_equal CONTAINER_SECONDS_EPOCH, entry['timestamp']['seconds'],
|
757
|
-
entry
|
758
|
-
assert_equal CONTAINER_NANOS, entry['timestamp']['nanos'], entry
|
759
|
-
assert_equal CONTAINER_SEVERITY, entry['severity'], entry
|
760
|
-
end
|
761
|
-
end
|
762
|
-
end
|
763
|
-
|
764
|
-
def test_one_container_log_metadata_from_tag
|
765
|
-
setup_gce_metadata_stubs
|
766
|
-
setup_container_metadata_stubs
|
767
|
-
setup_logging_stubs do
|
768
|
-
d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
|
769
|
-
d.emit(container_log_entry(log_entry(0)))
|
770
|
-
d.run
|
771
|
-
end
|
772
|
-
verify_log_entries(1, CONTAINER_FROM_TAG_PARAMS) do |entry|
|
773
|
-
assert_equal CONTAINER_SECONDS_EPOCH, entry['timestamp']['seconds'], entry
|
774
|
-
assert_equal CONTAINER_NANOS, entry['timestamp']['nanos'], entry
|
775
|
-
assert_equal CONTAINER_SEVERITY, entry['severity'], entry
|
776
|
-
end
|
712
|
+
# Test container logs when metadata is extracted from the tag.
|
713
|
+
def test_container_logs_metadata_from_tag
|
714
|
+
verify_container_logs(method(:container_log_entry),
|
715
|
+
CONTAINER_FROM_TAG_PARAMS)
|
777
716
|
end
|
778
717
|
|
779
718
|
def test_one_container_log_from_tag_stderr
|
@@ -840,6 +779,134 @@ module BaseTest
|
|
840
779
|
end
|
841
780
|
end
|
842
781
|
|
782
|
+
# Docker Container.
|
783
|
+
|
784
|
+
# Test textPayload logs from Docker container stderr / stdout.
|
785
|
+
def test_text_payload_docker_container_logs
|
786
|
+
setup_gce_metadata_stubs
|
787
|
+
[1, 2, 3, 5, 11, 50].each do |n|
|
788
|
+
@logs_sent = []
|
789
|
+
setup_logging_stubs do
|
790
|
+
d = create_driver(APPLICATION_DEFAULT_CONFIG, DOCKER_CONTAINER_TAG)
|
791
|
+
# Generate log entries with 'log' (simply a string) and 'time' fields.
|
792
|
+
n.times { |i| d.emit(docker_container_log_entry(log_entry(i))) }
|
793
|
+
d.run
|
794
|
+
end
|
795
|
+
# 'container_id' and 'container_name' should have been extracted from tag
|
796
|
+
# and properly set in resource.labels and common metadata labels as in
|
797
|
+
# DOCKER_CONTAINER_PARAMS.
|
798
|
+
verify_log_entries(n, DOCKER_CONTAINER_PARAMS) do |entry|
|
799
|
+
# Timestamp in 'time' field from log entry should be set properly.
|
800
|
+
assert_equal DOCKER_CONTAINER_SECONDS_EPOCH,
|
801
|
+
entry['timestamp']['seconds'], entry
|
802
|
+
assert_equal DOCKER_CONTAINER_NANOS, entry['timestamp']['nanos'],
|
803
|
+
entry
|
804
|
+
# Severity is 'DEFAULT' because 'stream' info is absent from log entry.
|
805
|
+
assert_equal_with_default entry['severity'], 'DEFAULT', 'DEFAULT', entry
|
806
|
+
end
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
# Test jsonPayload logs from Docker container stderr / stdout.
|
811
|
+
def test_json_payload_docker_container_logs
|
812
|
+
setup_gce_metadata_stubs
|
813
|
+
[1, 2, 3, 5, 11, 50].each do |n|
|
814
|
+
@logs_sent = []
|
815
|
+
setup_logging_stubs do
|
816
|
+
d = create_driver(APPLICATION_DEFAULT_CONFIG, DOCKER_CONTAINER_TAG)
|
817
|
+
n.times do
|
818
|
+
# Generate log entries with 'log' (json) and 'time' fields.
|
819
|
+
d.emit(docker_container_log_entry('{"msg": "test log entry ' \
|
820
|
+
"#{n}" \
|
821
|
+
'", "tag2": "test", "data": ' \
|
822
|
+
'5000, "severity": "WARNING"}'))
|
823
|
+
end
|
824
|
+
d.run
|
825
|
+
end
|
826
|
+
# 'container_id' and 'container_name' should have been extracted from tag
|
827
|
+
# and properly set in resource.labels and common metadata labels as in
|
828
|
+
# DOCKER_CONTAINER_PARAMS.
|
829
|
+
verify_log_entries(n, DOCKER_CONTAINER_PARAMS, 'jsonPayload') do |entry|
|
830
|
+
# 'log' field should be detected as json and parsed properly.
|
831
|
+
fields = get_fields(entry['jsonPayload'])
|
832
|
+
assert_equal 3, fields.size, entry
|
833
|
+
assert_equal "test log entry #{n}", get_string(fields['msg']), entry
|
834
|
+
assert_equal 'test', get_string(fields['tag2']), entry
|
835
|
+
assert_equal 5000, get_number(fields['data']), entry
|
836
|
+
# Timestamp in 'time' field from log entry should be set properly.
|
837
|
+
assert_equal DOCKER_CONTAINER_SECONDS_EPOCH,
|
838
|
+
entry['timestamp']['seconds'], entry
|
839
|
+
assert_equal DOCKER_CONTAINER_NANOS, entry['timestamp']['nanos'], entry
|
840
|
+
# Severity in 'severity' field from log entry should be set properly.
|
841
|
+
assert_equal 'WARNING', entry['severity'], entry
|
842
|
+
end
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
# Test the following metadata is properly extracted from json record:
|
847
|
+
# * container_id
|
848
|
+
# * container_name
|
849
|
+
# * source (this field maps to the 'stream' metadata label.
|
850
|
+
def test_docker_container_logs_metadata_from_json_record
|
851
|
+
setup_gce_metadata_stubs
|
852
|
+
{
|
853
|
+
# 'stream' label should be extracted from json record when present.
|
854
|
+
docker_container_log_entry_with_metadata(
|
855
|
+
log_entry(0)
|
856
|
+
) => {
|
857
|
+
# When the 'source' field from the json record has value 'stdout',
|
858
|
+
# 'severity' should be 'INFO'.
|
859
|
+
'params' => DOCKER_CONTAINER_PARAMS_WITH_STREAM_STDOUT,
|
860
|
+
'severity' => 'INFO'
|
861
|
+
},
|
862
|
+
# 'container_id' and 'container_name' can be extracted from tag or
|
863
|
+
# json record. If present in both cases, values in the json record will
|
864
|
+
# overwrite values in tags. For example:
|
865
|
+
# DOCKER_CONTAINER_PARAMS_WITH_METADATA_OVERWRITTEN has different
|
866
|
+
# 'container_id' and 'container_name' values from DOCKER_CONTAINER_TAG,
|
867
|
+
# and we need to verify these two fields get overwritten as expected.
|
868
|
+
docker_container_log_entry_with_metadata(
|
869
|
+
log_entry(0), DOCKER_CONTAINER_ID2, DOCKER_CONTAINER_NAME2,
|
870
|
+
DOCKER_CONTAINER_STREAM_STDERR
|
871
|
+
) => {
|
872
|
+
# When the 'source' field from the json record has value 'stderr',
|
873
|
+
# 'severity' should be 'ERROR'.
|
874
|
+
'params' => DOCKER_CONTAINER_PARAMS_WITH_METADATA_OVERWRITTEN,
|
875
|
+
'severity' => 'ERROR'
|
876
|
+
}
|
877
|
+
}.each do |log_entry, expected|
|
878
|
+
@logs_sent = []
|
879
|
+
setup_logging_stubs do
|
880
|
+
d = create_driver(APPLICATION_DEFAULT_CONFIG, DOCKER_CONTAINER_TAG)
|
881
|
+
d.emit(log_entry)
|
882
|
+
d.run
|
883
|
+
end
|
884
|
+
verify_log_entries(1, expected['params']) do |entry|
|
885
|
+
assert_equal DOCKER_CONTAINER_SECONDS_EPOCH,
|
886
|
+
entry['timestamp']['seconds'], entry
|
887
|
+
assert_equal DOCKER_CONTAINER_NANOS, entry['timestamp']['nanos'],
|
888
|
+
entry
|
889
|
+
assert_equal_with_default entry['severity'], expected['severity'],
|
890
|
+
'DEFAULT', entry
|
891
|
+
end
|
892
|
+
end
|
893
|
+
end
|
894
|
+
|
895
|
+
# Test logs from applications running in Docker containers.
|
896
|
+
def test_docker_container_application_logs
|
897
|
+
setup_gce_metadata_stubs
|
898
|
+
setup_docker_remote_api_stubs
|
899
|
+
setup_logging_stubs do
|
900
|
+
# Metadata Agent is not enabled. Will call Docker Remote API for
|
901
|
+
# container info.
|
902
|
+
d = create_driver(APPLICATION_DEFAULT_CONFIG,
|
903
|
+
DOCKER_CONTAINER_TAG_WITH_APPLICATION)
|
904
|
+
d.emit('message' => log_entry(0))
|
905
|
+
d.run
|
906
|
+
end
|
907
|
+
verify_log_entries(1, DOCKER_CONTAINER_WITH_APPLICATION_PARAMS)
|
908
|
+
end
|
909
|
+
|
843
910
|
def test_cloudfunctions_log
|
844
911
|
setup_gce_metadata_stubs
|
845
912
|
setup_cloudfunctions_metadata_stubs
|
@@ -1015,6 +1082,167 @@ module BaseTest
|
|
1015
1082
|
end
|
1016
1083
|
end
|
1017
1084
|
|
1085
|
+
def test_trace_field_assignment
|
1086
|
+
setup_gce_metadata_stubs
|
1087
|
+
message = log_entry(0)
|
1088
|
+
trace = 'projects/project-1/traces/1234567890abcdef1234567890abcdef'
|
1089
|
+
[
|
1090
|
+
{
|
1091
|
+
# It leaves trace entry field nil if no trace value sent.
|
1092
|
+
driver_config: APPLICATION_DEFAULT_CONFIG,
|
1093
|
+
emitted_log: { 'msg' => message },
|
1094
|
+
expected_trace_value: nil
|
1095
|
+
},
|
1096
|
+
{
|
1097
|
+
# By default, it sets trace via Google-specific key.
|
1098
|
+
driver_config: APPLICATION_DEFAULT_CONFIG,
|
1099
|
+
emitted_log: { 'msg' => message, DEFAULT_TRACE_KEY => trace },
|
1100
|
+
expected_trace_value: trace
|
1101
|
+
},
|
1102
|
+
{
|
1103
|
+
# It allows setting the trace via a custom configured key.
|
1104
|
+
driver_config: CONFIG_CUSTOM_TRACE_KEY_SPECIFIED,
|
1105
|
+
emitted_log: { 'msg' => message, 'custom_trace_key' => trace },
|
1106
|
+
expected_trace_value: trace
|
1107
|
+
},
|
1108
|
+
{
|
1109
|
+
# It no longer sets trace by the default key if custom key specified.
|
1110
|
+
driver_config: CONFIG_CUSTOM_TRACE_KEY_SPECIFIED,
|
1111
|
+
emitted_log: { 'msg' => message, DEFAULT_TRACE_KEY => trace },
|
1112
|
+
expected_trace_value: nil
|
1113
|
+
}
|
1114
|
+
].each do |input|
|
1115
|
+
setup_logging_stubs do
|
1116
|
+
@logs_sent = []
|
1117
|
+
d = create_driver(input[:driver_config])
|
1118
|
+
d.emit(input[:emitted_log])
|
1119
|
+
d.run
|
1120
|
+
end
|
1121
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
1122
|
+
assert_equal input[:expected_trace_value], entry['trace'], input
|
1123
|
+
end
|
1124
|
+
end
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
def test_trace_removal_from_json_payload
|
1128
|
+
setup_gce_metadata_stubs
|
1129
|
+
message = log_entry(0)
|
1130
|
+
trace = 'projects/project-1/traces/1234567890abcdef1234567890abcdef'
|
1131
|
+
[
|
1132
|
+
{
|
1133
|
+
# By default, it removes trace value from jsonPayload.
|
1134
|
+
driver_config: APPLICATION_DEFAULT_CONFIG,
|
1135
|
+
emitted_log: { 'msg' => message, DEFAULT_TRACE_KEY => trace },
|
1136
|
+
expected_json_payload: { 'msg' => message }
|
1137
|
+
},
|
1138
|
+
{
|
1139
|
+
# It keeps the trace value in jsonPayload if keep_trace_key set to true.
|
1140
|
+
driver_config: CONFIG_KEEP_TRACE_KEY_TRUE,
|
1141
|
+
emitted_log: { 'msg' => message, DEFAULT_TRACE_KEY => trace },
|
1142
|
+
expected_json_payload: { 'msg' => message, DEFAULT_TRACE_KEY => trace }
|
1143
|
+
}
|
1144
|
+
].each do |input|
|
1145
|
+
setup_logging_stubs do
|
1146
|
+
@logs_sent = []
|
1147
|
+
d = create_driver(input[:driver_config])
|
1148
|
+
d.emit(input[:emitted_log])
|
1149
|
+
d.run
|
1150
|
+
end
|
1151
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
1152
|
+
fields = get_fields(entry['jsonPayload'])
|
1153
|
+
assert_equal input[:expected_json_payload].size, fields.size, input
|
1154
|
+
fields.each do |key, value|
|
1155
|
+
assert_equal(input[:expected_json_payload][key],
|
1156
|
+
get_string(value), input)
|
1157
|
+
end
|
1158
|
+
end
|
1159
|
+
end
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
# Metadata Agent related tests.
|
1163
|
+
def test_configure_enable_metadata_agent_default_and_false
|
1164
|
+
setup_gce_metadata_stubs
|
1165
|
+
[create_driver, create_driver(DISABLE_METADATA_AGENT_CONFIG)].each do |d|
|
1166
|
+
assert_false d.instance.instance_variable_get(:@enable_metadata_agent)
|
1167
|
+
end
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
def test_configure_enable_metadata_agent_true
|
1171
|
+
setup_gce_metadata_stubs
|
1172
|
+
setup_metadata_agent_stubs(IMPLICIT_MONITORED_RESOURCE_UNIQUE_KEY)
|
1173
|
+
d = create_driver(ENABLE_METADATA_AGENT_CONFIG)
|
1174
|
+
assert_true d.instance.instance_variable_get(:@enable_metadata_agent)
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
# Test an implicit monitored resource can be retrieved from Metadata Agent
|
1178
|
+
# with an empty string as the locally-unique id.
|
1179
|
+
def test_retrieve_implicit_monitored_resource
|
1180
|
+
# Minimum set up for gce metadata stubs. Stubs for 'vm_id' and 'location'
|
1181
|
+
# info are deliberately not set up.
|
1182
|
+
setup_gce_metadata_stubs_minimum
|
1183
|
+
setup_metadata_agent_stubs(IMPLICIT_MONITORED_RESOURCE_UNIQUE_KEY)
|
1184
|
+
setup_logging_stubs do
|
1185
|
+
d = create_driver(ENABLE_METADATA_AGENT_CONFIG)
|
1186
|
+
d.emit('message' => log_entry(0))
|
1187
|
+
d.run
|
1188
|
+
end
|
1189
|
+
verify_log_entries(1, COMPUTE_PARAMS)
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
# Test a docker container monitored resource can be retrieved from Metadata
|
1193
|
+
# Agent with "container.<container_id>" as the locally-unique id.
|
1194
|
+
def test_retrieve_docker_container_monitored_resource
|
1195
|
+
setup_gce_metadata_stubs_minimum
|
1196
|
+
setup_metadata_agent_stubs(IMPLICIT_MONITORED_RESOURCE_UNIQUE_KEY)
|
1197
|
+
setup_metadata_agent_stubs(DOCKER_CONSTANTS[:resource_type])
|
1198
|
+
setup_logging_stubs do
|
1199
|
+
# Tag format here: "container.<container_id>.<container_name>"
|
1200
|
+
d = create_driver(ENABLE_METADATA_AGENT_CONFIG, DOCKER_CONTAINER_TAG)
|
1201
|
+
d.emit('message' => log_entry(0))
|
1202
|
+
d.run
|
1203
|
+
end
|
1204
|
+
# gce_metadata_stubs has ZONE1, while metadata agent stub has ZONE2. Here we
|
1205
|
+
# need to verify ZONE2 overwrites ZONE1 as expected.
|
1206
|
+
verify_log_entries(1, DOCKER_CONTAINER_PARAMS_WITH_ZONE2)
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
# Test a docker container monitored resource can be retrieved from Metadata
|
1210
|
+
# Agent with "container.<container_name>" as the locally-unique id when the
|
1211
|
+
# log entry comes from an application running in the docker container.
|
1212
|
+
def test_retrieve_docker_container_monitored_resource_with_application
|
1213
|
+
setup_gce_metadata_stubs_minimum
|
1214
|
+
setup_metadata_agent_stubs(IMPLICIT_MONITORED_RESOURCE_UNIQUE_KEY)
|
1215
|
+
setup_metadata_agent_stubs(
|
1216
|
+
"#{DOCKER_CONSTANTS[:resource_type]}_application")
|
1217
|
+
setup_logging_stubs do
|
1218
|
+
# Tag format here: "application-container.<container_name>.
|
1219
|
+
# <additional_tag>"
|
1220
|
+
d = create_driver(ENABLE_METADATA_AGENT_CONFIG,
|
1221
|
+
DOCKER_CONTAINER_TAG_WITH_APPLICATION)
|
1222
|
+
d.emit('message' => log_entry(0))
|
1223
|
+
d.run
|
1224
|
+
end
|
1225
|
+
verify_log_entries(1, DOCKER_CONTAINER_WITH_APPLICATION_PARAMS)
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
# Test a GKE container monitored resource can be retrieved from Metadata
|
1229
|
+
# Agent with "gke_containerName.<namespace_id>.<pod_name>.<container_name>" as
|
1230
|
+
# the locally-unique id when the log entry comes from an application running
|
1231
|
+
# in Kubenetes.
|
1232
|
+
def test_retrieve_gke_application_container_monitored_resource
|
1233
|
+
setup_gce_metadata_stubs_minimum
|
1234
|
+
setup_container_metadata_stubs
|
1235
|
+
setup_metadata_agent_stubs(IMPLICIT_MONITORED_RESOURCE_UNIQUE_KEY)
|
1236
|
+
setup_metadata_agent_stubs(
|
1237
|
+
"#{CONTAINER_CONSTANTS[:resource_type]}_application")
|
1238
|
+
setup_logging_stubs do
|
1239
|
+
d = create_driver(ENABLE_METADATA_AGENT_CONFIG)
|
1240
|
+
d.emit(gke_application_container_log_entry(log_entry(0)))
|
1241
|
+
d.run
|
1242
|
+
end
|
1243
|
+
verify_log_entries(1, CONTAINER_FROM_APPLICATION_PARAMS)
|
1244
|
+
end
|
1245
|
+
|
1018
1246
|
private
|
1019
1247
|
|
1020
1248
|
def stub_metadata_request(metadata_path, response_body)
|
@@ -1051,6 +1279,26 @@ module BaseTest
|
|
1051
1279
|
'Content-Type' => 'application/json' })
|
1052
1280
|
end
|
1053
1281
|
|
1282
|
+
# The minimum stubs needed for infomation that Metadata Agent can not provide.
|
1283
|
+
def setup_gce_metadata_stubs_minimum
|
1284
|
+
# Stub the root, used for platform detection by the plugin and 'googleauth'.
|
1285
|
+
stub_request(:get, 'http://169.254.169.254')
|
1286
|
+
.to_return(status: 200, headers: { 'Metadata-Flavor' => 'Google' })
|
1287
|
+
|
1288
|
+
# Create stubs for all the GCE metadata lookups the agent needs to make.
|
1289
|
+
stub_metadata_request('project/project-id', PROJECT_ID)
|
1290
|
+
stub_metadata_request('instance/attributes/',
|
1291
|
+
"attribute1\nattribute2\nattribute3")
|
1292
|
+
|
1293
|
+
# Used by 'googleauth' to fetch the default service account credentials.
|
1294
|
+
stub_request(:get, 'http://169.254.169.254/computeMetadata/v1/' \
|
1295
|
+
'instance/service-accounts/default/token')
|
1296
|
+
.to_return(body: %({"access_token": "#{FAKE_AUTH_TOKEN}"}),
|
1297
|
+
status: 200,
|
1298
|
+
headers: { 'Content-Length' => FAKE_AUTH_TOKEN.length,
|
1299
|
+
'Content-Type' => 'application/json' })
|
1300
|
+
end
|
1301
|
+
|
1054
1302
|
def setup_ec2_metadata_stubs
|
1055
1303
|
# Stub the root, used for platform detection.
|
1056
1304
|
stub_request(:get, 'http://169.254.169.254')
|
@@ -1101,6 +1349,11 @@ module BaseTest
|
|
1101
1349
|
'KUBE_BEARER_TOKEN: AoQiMuwkNP2BMT0S')
|
1102
1350
|
end
|
1103
1351
|
|
1352
|
+
def setup_docker_remote_api_stubs
|
1353
|
+
stub_request(:get, "http://unix/containers/#{DOCKER_CONTAINER_NAME}/json")
|
1354
|
+
.to_return(status: 200, body: "{\"Id\":\"#{DOCKER_CONTAINER_ID}\"}")
|
1355
|
+
end
|
1356
|
+
|
1104
1357
|
def setup_cloudfunctions_metadata_stubs
|
1105
1358
|
stub_metadata_request(
|
1106
1359
|
'instance/attributes/',
|
@@ -1130,11 +1383,20 @@ module BaseTest
|
|
1130
1383
|
Prometheus::Client.registry.instance_variable_set('@metrics', {})
|
1131
1384
|
end
|
1132
1385
|
|
1386
|
+
def setup_metadata_agent_stubs(resource_type)
|
1387
|
+
unique_id = MONITORED_RESOURCE_STUBS[resource_type]['unique_id']
|
1388
|
+
resource = MONITORED_RESOURCE_STUBS[resource_type]['monitored_resource']
|
1389
|
+
stub_request(:get, 'http://local-metadata-agent.stackdriver.com:8000' \
|
1390
|
+
"/monitoredResource/#{unique_id}")
|
1391
|
+
.to_return(status: 200, body: resource)
|
1392
|
+
end
|
1393
|
+
|
1133
1394
|
def container_tag_with_container_name(container_name)
|
1134
1395
|
"kubernetes.#{CONTAINER_POD_NAME}_#{CONTAINER_NAMESPACE_NAME}_" \
|
1135
1396
|
"#{container_name}"
|
1136
1397
|
end
|
1137
1398
|
|
1399
|
+
# GKE Container
|
1138
1400
|
def container_log_entry_with_metadata(
|
1139
1401
|
log, container_name = CONTAINER_CONTAINER_NAME)
|
1140
1402
|
{
|
@@ -1162,6 +1424,37 @@ module BaseTest
|
|
1162
1424
|
}
|
1163
1425
|
end
|
1164
1426
|
|
1427
|
+
def gke_application_container_log_entry(log)
|
1428
|
+
{
|
1429
|
+
log: log,
|
1430
|
+
LOCALLY_UNIQUE_ID_LABEL_NAME => 'gke_containerName' \
|
1431
|
+
".#{CONTAINER_NAMESPACE_ID}" \
|
1432
|
+
".#{CONTAINER_POD_NAME}" \
|
1433
|
+
".#{CONTAINER_CONTAINER_NAME}"
|
1434
|
+
}
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
# Docker Container
|
1438
|
+
def docker_container_log_entry_with_metadata(
|
1439
|
+
log, container_id = DOCKER_CONTAINER_ID,
|
1440
|
+
container_name = DOCKER_CONTAINER_NAME,
|
1441
|
+
stream = DOCKER_CONTAINER_STREAM_STDOUT)
|
1442
|
+
{
|
1443
|
+
log: log,
|
1444
|
+
container_id: container_id,
|
1445
|
+
container_name: container_name,
|
1446
|
+
time: DOCKER_CONTAINER_TIMESTAMP,
|
1447
|
+
source: stream
|
1448
|
+
}
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
def docker_container_log_entry(log)
|
1452
|
+
{
|
1453
|
+
log: log,
|
1454
|
+
time: CONTAINER_TIMESTAMP
|
1455
|
+
}
|
1456
|
+
end
|
1457
|
+
|
1165
1458
|
def cloudfunctions_log_entry(i)
|
1166
1459
|
{
|
1167
1460
|
stream: 'stdout',
|
@@ -1252,6 +1545,25 @@ module BaseTest
|
|
1252
1545
|
assert i == n, "Number of entries #{i} does not match expected number #{n}"
|
1253
1546
|
end
|
1254
1547
|
|
1548
|
+
def verify_container_logs(log_entry_method, expected_params)
|
1549
|
+
setup_gce_metadata_stubs
|
1550
|
+
setup_container_metadata_stubs
|
1551
|
+
[1, 2, 3, 5, 11, 50].each do |n|
|
1552
|
+
@logs_sent = []
|
1553
|
+
setup_logging_stubs do
|
1554
|
+
d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
|
1555
|
+
n.times { |i| d.emit(log_entry_method.call(log_entry(i))) }
|
1556
|
+
d.run
|
1557
|
+
end
|
1558
|
+
verify_log_entries(n, expected_params) do |entry|
|
1559
|
+
assert_equal CONTAINER_SECONDS_EPOCH, entry['timestamp']['seconds'],
|
1560
|
+
entry
|
1561
|
+
assert_equal CONTAINER_NANOS, entry['timestamp']['nanos'], entry
|
1562
|
+
assert_equal CONTAINER_SEVERITY, entry['severity'], entry
|
1563
|
+
end
|
1564
|
+
end
|
1565
|
+
end
|
1566
|
+
|
1255
1567
|
# Replace the 'referer' field with nil.
|
1256
1568
|
def http_request_message_with_nil_referer
|
1257
1569
|
HTTP_REQUEST_MESSAGE.merge('referer' => nil)
|