From 1eb4e79057f986e00a50627b26024b70acbe48c4 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Thu, 28 May 2020 14:56:43 -0600 Subject: [PATCH] Add memory metrics into compute googlecloud (#18802) * Add memory metrics into compute googlecloud * update unit test and data.json for memory metrics --- CHANGELOG.next.asciidoc | 2 + metricbeat/docs/fields.asciidoc | 40 ++++++++++ .../module/googlecloud/_meta/fields.yml | 6 ++ .../googlecloud/compute/_meta/data.json | 59 +++++++++----- .../googlecloud/compute/_meta/data_cpu.json | 38 ++++++--- .../googlecloud/compute/_meta/data_disk.json | 16 ++-- .../compute/_meta/data_firewall.json | 36 ++++++--- .../compute/_meta/data_memory.json | 78 +++++++++++++++++++ .../compute/_meta/data_network.json | 21 ++--- .../googlecloud/compute/_meta/docs.asciidoc | 14 ++++ .../googlecloud/compute/_meta/fields.yml | 15 ++++ .../compute/compute_integration_test.go | 1 + .../module/googlecloud/compute/manifest.yml | 5 ++ .../metricbeat/module/googlecloud/fields.go | 2 +- 14 files changed, 274 insertions(+), 59 deletions(-) create mode 100644 x-pack/metricbeat/module/googlecloud/compute/_meta/data_memory.json diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 596c26c3576..36cf17b9775 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -206,6 +206,7 @@ field. You can revert this change by configuring tags for the module and omittin - Remove specific win32 api errors from events in perfmon. {issue}18292[18292] {pull}18361[18361] - Fix application_pool metricset after pdh changes. {pull}18477[18477] - Fix tags_filter for cloudwatch metricset in aws. {pull}18524[18524] +- Add missing network.sent_packets_count metric into compute metricset in googlecloud module. {pull}18802[18802] *Packetbeat* @@ -440,6 +441,7 @@ field. You can revert this change by configuring tags for the module and omittin - Update MSSQL module to fix some SSPI authentication and add brackets to USE statements {pull}17862[17862]] - Add client address to events from http server module {pull}18336[18336] - Remove required for region/zone and make stackdriver a metricset in googlecloud. {issue}16785[16785] {pull}18398[18398] +- Add memory metrics into compute googlecloud. {pull}18802[18802] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 735a257727c..f0038326cd4 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -18232,6 +18232,9 @@ GCP module *`googlecloud.labels`*:: + -- +Google cloud monitoring metrics labels + + type: object -- @@ -18383,6 +18386,43 @@ type: long -- + +*`googlecloud.compute.instance.memory.balloon.ram_size.value`*:: ++ +-- +The total amount of memory in the VM. This metric is only available for VMs that belong to the e2 family. + +type: long + +-- + +*`googlecloud.compute.instance.memory.balloon.ram_used.value`*:: ++ +-- +Memory currently used in the VM. This metric is only available for VMs that belong to the e2 family. + +type: long + +-- + +*`googlecloud.compute.instance.memory.balloon.swap_in_bytes_count.value`*:: ++ +-- +The amount of memory read into the guest from its own swap space. This metric is only available for VMs that belong to the e2 family. + +type: long + +-- + +*`googlecloud.compute.instance.memory.balloon.swap_out_bytes_count.value`*:: ++ +-- +The amount of memory written from the guest to its own swap space. This metric is only available for VMs that belong to the e2 family. + +type: long + +-- + [float] === loadbalancing diff --git a/x-pack/metricbeat/module/googlecloud/_meta/fields.yml b/x-pack/metricbeat/module/googlecloud/_meta/fields.yml index 41c1c09fad9..3ab4238b736 100644 --- a/x-pack/metricbeat/module/googlecloud/_meta/fields.yml +++ b/x-pack/metricbeat/module/googlecloud/_meta/fields.yml @@ -9,15 +9,21 @@ fields: - name: labels type: object + description: > + Google cloud monitoring metrics labels fields: - name: user.* type: object + object_type: keyword - name: metadata.* type: object + object_type: keyword - name: metrics.* type: object + object_type: keyword - name: system.* type: object + object_type: keyword - name: "stackdriver.*.*.*.*" type: object object_type: double diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/data.json b/x-pack/metricbeat/module/googlecloud/compute/_meta/data.json index 4a3ab08217c..13c4958d13f 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/_meta/data.json +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/data.json @@ -5,15 +5,15 @@ "id": "elastic-observability" }, "instance": { - "id": "1174463293187628268", - "name": "gke-observability-8--observability-8--bc1afd95-ngmh" + "id": "7692260917184259934", + "name": "instance-test-ks" }, "machine": { - "type": "n1-standard-4" + "type": "e2-standard-2" }, "provider": "googlecloud" }, - "cloud.availability_zone": "europe-west1-c", + "cloud.availability_zone": "us-central1-a", "event": { "dataset": "googlecloud.compute", "duration": 115000, @@ -21,31 +21,50 @@ }, "googlecloud": { "compute": { + "firewall": { + "dropped_bytes_count": { + "value": 171 + }, + "dropped_packets_count": { + "value": 4 + } + }, "instance": { - "disk": { - "read_bytes_count": { - "value": 0 - }, - "read_ops_count": { - "value": 0 + "cpu": { + "reserved_cores": { + "value": 2 }, - "write_bytes_count": { - "value": 0 + "usage_time": { + "value": 0.1803964574089818 }, - "write_ops_count": { - "value": 0 + "utilization": { + "value": 0.001503303811741515 } + }, + "memory": { + "balloon": { + "ram_size": { + "value": 7896264704 + }, + "ram_used": { + "value": 416518144 + }, + "swap_in_bytes_count": { + "value": 0 + }, + "swap_out_bytes_count": { + "value": 0 + } + } + }, + "uptime": { + "value": 60.000000000000455 } } }, "labels": { - "metrics": { - "device_name": "disk-2", - "device_type": "permanent", - "storage_type": "pd-standard" - }, "user": { - "goog-gke-node": "" + "created-by": "ks" } } }, diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_cpu.json b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_cpu.json index 1d3a120a218..13c4958d13f 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_cpu.json +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_cpu.json @@ -5,15 +5,15 @@ "id": "elastic-observability" }, "instance": { - "id": "1174463293187628268", - "name": "gke-observability-8--observability-8--bc1afd95-ngmh" + "id": "7692260917184259934", + "name": "instance-test-ks" }, "machine": { - "type": "n1-standard-4" + "type": "e2-standard-2" }, "provider": "googlecloud" }, - "cloud.availability_zone": "europe-west1-c", + "cloud.availability_zone": "us-central1-a", "event": { "dataset": "googlecloud.compute", "duration": 115000, @@ -23,32 +23,48 @@ "compute": { "firewall": { "dropped_bytes_count": { - "value": 181 + "value": 171 }, "dropped_packets_count": { - "value": 3 + "value": 4 } }, "instance": { "cpu": { "reserved_cores": { - "value": 4 + "value": 2 }, "usage_time": { - "value": 63.478293027728796 + "value": 0.1803964574089818 }, "utilization": { - "value": 0.26449288761553663 + "value": 0.001503303811741515 + } + }, + "memory": { + "balloon": { + "ram_size": { + "value": 7896264704 + }, + "ram_used": { + "value": 416518144 + }, + "swap_in_bytes_count": { + "value": 0 + }, + "swap_out_bytes_count": { + "value": 0 + } } }, "uptime": { - "value": 60 + "value": 60.000000000000455 } } }, "labels": { "user": { - "goog-gke-node": "" + "created-by": "ks" } } }, diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_disk.json b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_disk.json index 8da39b6ab7d..38b0e2a5b4f 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_disk.json +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_disk.json @@ -5,15 +5,15 @@ "id": "elastic-observability" }, "instance": { - "id": "8390997210852978465", - "name": "gke-observability-7--observability-7--3dd3e39b-0jm5" + "id": "7692260917184259934", + "name": "instance-test-ks" }, "machine": { - "type": "n1-standard-4" + "type": "e2-standard-2" }, "provider": "googlecloud" }, - "cloud.availability_zone": "europe-west1-c", + "cloud.availability_zone": "us-central1-a", "event": { "dataset": "googlecloud.compute", "duration": 115000, @@ -30,22 +30,22 @@ "value": 0 }, "write_bytes_count": { - "value": 0 + "value": 158506 }, "write_ops_count": { - "value": 0 + "value": 25 } } } }, "labels": { "metrics": { - "device_name": "gke-observability-7-1--pvc-65581044-7d5d-11ea-8cd9-42010af0011c", + "device_name": "instance-test-ks", "device_type": "permanent", "storage_type": "pd-standard" }, "user": { - "goog-gke-node": "" + "created-by": "ks" } } }, diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_firewall.json b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_firewall.json index 04b750b8b7d..f147f276f32 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_firewall.json +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_firewall.json @@ -5,15 +5,15 @@ "id": "elastic-observability" }, "instance": { - "id": "2528596280375797115", - "name": "gke-dev-next-oblt-dev-next-oblt-pool-404d7f0c-cpj6" + "id": "7692260917184259934", + "name": "instance-test-ks" }, "machine": { - "type": "n1-standard-4" + "type": "e2-standard-2" }, "provider": "googlecloud" }, - "cloud.availability_zone": "europe-west1-c", + "cloud.availability_zone": "us-central1-a", "event": { "dataset": "googlecloud.compute", "duration": 115000, @@ -23,22 +23,38 @@ "compute": { "firewall": { "dropped_bytes_count": { - "value": 386 + "value": 277 }, "dropped_packets_count": { - "value": 7 + "value": 5 } }, "instance": { "cpu": { "reserved_cores": { - "value": 4 + "value": 2 }, "usage_time": { - "value": 106.88293868489563 + "value": 0.18404532833979204 }, "utilization": { - "value": 0.4453455778537318 + "value": 0.001533711069498267 + } + }, + "memory": { + "balloon": { + "ram_size": { + "value": 7896264704 + }, + "ram_used": { + "value": 416260096 + }, + "swap_in_bytes_count": { + "value": 0 + }, + "swap_out_bytes_count": { + "value": 0 + } } }, "uptime": { @@ -48,7 +64,7 @@ }, "labels": { "user": { - "goog-gke-node": "" + "created-by": "ks" } } }, diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_memory.json b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_memory.json new file mode 100644 index 00000000000..f147f276f32 --- /dev/null +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_memory.json @@ -0,0 +1,78 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "cloud": { + "account": { + "id": "elastic-observability" + }, + "instance": { + "id": "7692260917184259934", + "name": "instance-test-ks" + }, + "machine": { + "type": "e2-standard-2" + }, + "provider": "googlecloud" + }, + "cloud.availability_zone": "us-central1-a", + "event": { + "dataset": "googlecloud.compute", + "duration": 115000, + "module": "googlecloud" + }, + "googlecloud": { + "compute": { + "firewall": { + "dropped_bytes_count": { + "value": 277 + }, + "dropped_packets_count": { + "value": 5 + } + }, + "instance": { + "cpu": { + "reserved_cores": { + "value": 2 + }, + "usage_time": { + "value": 0.18404532833979204 + }, + "utilization": { + "value": 0.001533711069498267 + } + }, + "memory": { + "balloon": { + "ram_size": { + "value": 7896264704 + }, + "ram_used": { + "value": 416260096 + }, + "swap_in_bytes_count": { + "value": 0 + }, + "swap_out_bytes_count": { + "value": 0 + } + } + }, + "uptime": { + "value": 60 + } + } + }, + "labels": { + "user": { + "created-by": "ks" + } + } + }, + "metricset": { + "name": "compute", + "period": 10000 + }, + "service": { + "type": "googlecloud" + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_network.json b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_network.json index d543fc2382f..1b86e390e16 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/_meta/data_network.json +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/data_network.json @@ -5,15 +5,15 @@ "id": "elastic-observability" }, "instance": { - "id": "7208038667777737825", - "name": "gke-dev-next-oblt-dev-next-oblt-pool-404d7f0c-fgxk" + "id": "7692260917184259934", + "name": "instance-test-ks" }, "machine": { - "type": "n1-standard-4" + "type": "e2-standard-2" }, "provider": "googlecloud" }, - "cloud.availability_zone": "europe-west1-c", + "cloud.availability_zone": "us-central1-a", "event": { "dataset": "googlecloud.compute", "duration": 115000, @@ -24,23 +24,26 @@ "instance": { "network": { "received_bytes_count": { - "value": 17913 + "value": 13073 }, "received_packets_count": { - "value": 128 + "value": 95 }, "sent_bytes_count": { - "value": 841 + "value": 0 + }, + "sent_packets_count": { + "value": 0 } } } }, "labels": { "metrics": { - "loadbalanced": "true" + "loadbalanced": "false" }, "user": { - "goog-gke-node": "" + "created-by": "ks" } } }, diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/docs.asciidoc b/x-pack/metricbeat/module/googlecloud/compute/_meta/docs.asciidoc index f72103099ea..03c3c9296ea 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/docs.asciidoc @@ -80,3 +80,17 @@ Here is a list of metrics collected by `compute` metricset: * `instance.network.sent_packets_count`: Count of packets sent over the network - `instance_name`: The name of the VM instance. - `loadBalanced`: Whether traffic was sent from an L3 loadbalanced IP address assigned to the VM. Traffic that is externally routed from the VM's standard internal or external IP address, such as L7 loadbalanced traffic, is not considered to be loadbalanced in this metric. + +[float] +==== memory +* `instance.memory.balloon.ram_size`: The total amount of memory in the VM. This metric is only available for VMs that belong to the e2 family. +- `instance_name`: The name of the VM instance. + +* `instance.memory.balloon.ram_used`: Memory currently used in the VM. This metric is only available for VMs that belong to the e2 family. +- `instance_name`: The name of the VM instance. + +* `instance.memory.balloon.swap_in_bytes_count`: The amount of memory read into the guest from its own swap space. This metric is only available for VMs that belong to the e2 family. +- `instance_name`: The name of the VM instance. + +* `instance.memory.balloon.swap_out_bytes_count`: The amount of memory written from the guest to its own swap space. This metric is only available for VMs that belong to the e2 family. +- `instance_name`: The name of the VM instance. diff --git a/x-pack/metricbeat/module/googlecloud/compute/_meta/fields.yml b/x-pack/metricbeat/module/googlecloud/compute/_meta/fields.yml index 5cbdfb3ea56..06895b42129 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/_meta/fields.yml +++ b/x-pack/metricbeat/module/googlecloud/compute/_meta/fields.yml @@ -60,3 +60,18 @@ - name: sent_packets_count.value type: long description: Count of packets sent over the network + - name: memory.balloon + type: group + fields: + - name: ram_size.value + type: long + description: The total amount of memory in the VM. This metric is only available for VMs that belong to the e2 family. + - name: ram_used.value + type: long + description: Memory currently used in the VM. This metric is only available for VMs that belong to the e2 family. + - name: swap_in_bytes_count.value + type: long + description: The amount of memory read into the guest from its own swap space. This metric is only available for VMs that belong to the e2 family. + - name: swap_out_bytes_count.value + type: long + description: The amount of memory written from the guest to its own swap space. This metric is only available for VMs that belong to the e2 family. diff --git a/x-pack/metricbeat/module/googlecloud/compute/compute_integration_test.go b/x-pack/metricbeat/module/googlecloud/compute/compute_integration_test.go index be2dd08cdec..275016a383d 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/compute_integration_test.go +++ b/x-pack/metricbeat/module/googlecloud/compute/compute_integration_test.go @@ -33,6 +33,7 @@ func TestData(t *testing.T) { {"googlecloud.compute.instance.network", "./_meta/data_network.json"}, {"googlecloud.compute.instance.cpu", "./_meta/data_cpu.json"}, {"googlecloud.compute.firewall", "./_meta/data_firewall.json"}, + {"googlecloud.compute.instance.memory", "./_meta/data_memory.json"}, } config := stackdriver.GetConfigForTest(t, "compute") diff --git a/x-pack/metricbeat/module/googlecloud/compute/manifest.yml b/x-pack/metricbeat/module/googlecloud/compute/manifest.yml index 34210db8c0e..03ec393868e 100644 --- a/x-pack/metricbeat/module/googlecloud/compute/manifest.yml +++ b/x-pack/metricbeat/module/googlecloud/compute/manifest.yml @@ -16,7 +16,12 @@ input: - "compute.googleapis.com/instance/disk/read_ops_count" - "compute.googleapis.com/instance/disk/write_bytes_count" - "compute.googleapis.com/instance/disk/write_ops_count" + - "compute.googleapis.com/instance/memory/balloon/ram_size" + - "compute.googleapis.com/instance/memory/balloon/ram_used" + - "compute.googleapis.com/instance/memory/balloon/swap_in_bytes_count" + - "compute.googleapis.com/instance/memory/balloon/swap_out_bytes_count" - "compute.googleapis.com/instance/network/received_bytes_count" - "compute.googleapis.com/instance/network/received_packets_count" - "compute.googleapis.com/instance/network/sent_bytes_count" + - "compute.googleapis.com/instance/network/sent_packets_count" - "compute.googleapis.com/instance/uptime" diff --git a/x-pack/metricbeat/module/googlecloud/fields.go b/x-pack/metricbeat/module/googlecloud/fields.go index 6d629ce05c2..a9ff234dca6 100644 --- a/x-pack/metricbeat/module/googlecloud/fields.go +++ b/x-pack/metricbeat/module/googlecloud/fields.go @@ -19,5 +19,5 @@ func init() { // AssetGooglecloud returns asset data. // This is the base64 encoded gzipped contents of module/googlecloud. func AssetGooglecloud() string { - return "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" + return "eJzsXV1v2zjWvu+vOJibNi/SFHj3rlgMkEl3Z4ptdoJNprcCRR3b3FCkhh/xuL9+QVKSJduSKVtSmiKdm4kl8TzPIXm+SErv4RE3H2Ep5ZIj5dJmbwAMMxw/wttf/a9w436GO07MQqr87RsAhRyJxo+QoiFvADLUVLHCMCk+ws9vAAB+vbmDXGaW4xuABUOe6Y/+wnsQJMddke6f2RTudyVtUf7SfK75LCcpcl3/XD0q0/8iNY2fD+Cq/pXcvHzIpWBGKiaWkKNRjOp9EbtYmnisRnX1f61LnZjcv/BjEu54xM1aquxgwzkakhFDpmrcUZ2kbb3RBvPRmq6a/UkbQh8zxZ6cwsN/Px0fB622M2lTPyoPXE1yUhRMLMtbf2o13jOabstRY1bEgEJjlcAMFkrmcO8Qf/KI4fruM/xpUW2u9phRmRfWNGHtTrI2x+Y02QPXmrg3oeWquyOHNBPaEEHxYAfuCu9qrNnggilcE873buhrtK/hZuOZkkWBWZJuDOqESivM1RPhdhd+WyKXYtlxQ0udnwWVuTMOvvlKGKQbMCvsI7YPsCD0Ec2EEEsB0SDr8VfYSXpGoUb1hFlCpUIdwXhvenZy/rfNU1QgF+DbrkWBFJ7zSmrjrrr/7xjObazWMM6+Edf6qEAfXAcoQt1fFSDCuaTEYAY3d38Eu8E0UKsUCsM3wITzKhWVOPiaLDExLMdR0f/hmoWFVA5zqWomQCOVItOdAypj+nGiEUWmmug3rj3XQ2GiO0nBiHeQ2QEliwkhOQgB0effQRao/Djd138T1Voxg/PoyokyKMDI48oKsKbXlpdzRF315Cl6J04vjBaE3+Ta3+fn7ddbWBENKaIAZYVgYnkZM3kEmrVUU80fiuxpMme5N4eCtDCPnE66uR3AOJW/rFFW/vI0nBqFmUePThJIF0QOwjab/uLwbVOPXKrNVeq8oBTTDHOSJ5p9i/GFsaSdHzfSEA4kr/gHJm5Oh/l+BQ8rpstg27l0KfgGyBNhnKQ8+NGvt2WmkGKwFNI/jP8PC5Iz3sgOuohZjdmIxG4DiW304dqfk5NekyJhYqKp5Pptr8e8K2WixLm0qE2Y+8xokGvhMYEuCMWZ+Es7lS05qIDKY9cGL+jAyMk1UJdxJMlSwomgrMVjrMz3iyQZ/FIJGJgAr4wpdh10t1U6A0QXkCaY1FlZkSWcGBSU4aGwrwXh2kVARrHUNpOO8PgGKOHUcp99+N5frzDMdYV/+kGwJqVFL9PHQsm/NlWPlmDACsN44/K+C63uDLK18b7MgVGoCyk0HpoV55v+s6fP1k2RmEzwaDupdU4yTOuYHDi2QVl05wDHFAlHlNkU93uvnDhZMfKaMv/xVyEFCsMI/8Wz7RMfDyEWRhPKUsm1WSULQo1Uvd23j6c3z94XpSnh/SHLvogeL7AvQNg8WTDh88Kg1jGk7dqp0o5EubP41Mq5MVEXfRpxMdGV5dLB+Pz28HD34d47GAgexgWmssKn9+1OF4NpsNdoy4pVuqmhucuH4MdADkZ1Vq0HkaXaaw7vpAJK6AovnNaH0VkoKYzjY2iRKLO7TrCH77Cr+8/DgzPf2irnkKQCJHQFVAqBoQ6Xolm7tJxy5smILLixV5d0VoOvLmkwhFgY8OqSBkjbLmQZVIKMue40JCr/ceLy48O5fxDHm8KIURRtDge0FW8ShzfabxbjLMVxGxFvHONtU5xlOtlEDjGS8WbyXEM50FSeaiwHmctRDOYRidv6e3z8fpTEiTF8CMx0fAC5D3864AcC+OEgB4TrYyq5FbJ3ZUql9vsI+FL4zM6v9mUtB7jr8ZbSwPXNv5rjCKQIrq7i79Xy6ude/Vy0VHj1cz+GnzvFy01RpRrs4Yb5txGLU0PhPXcharBXi/dpL9CjvZavXstXr+Wrl1O+qtfH/3bVUb2aeSG6AoRLhVpHmPUeNcaZdG/nPn/5ZVuqqow3vFtIBQ83d7Dgcq2Bmbc62KftDm0pgBQFZ9Rv+gNtFJLc71m42LWPO9Ri9kudRq61UaqHXulDHLkurEzM2w8lMiNbkKfph4rbnB1xkF8XQGVMT3xwJDporUr53XJOgdtVKe2XqhwKr9R9Z95nko8XrM+qMUS68Kg2Yt33kMb6XPc4Gf0xpz1ucjvQXU+T557iqAe46VOcdLSLPttBH3HPhhaJ1jzxEfrzOujGFOdS+9M2tUkZIfNqnrTZmiq/2W+NCsGgypnwiU5l1D7c33/pWlAfHE6chnXXjX29bbhZq/1pqX6A42xF0LmUZoWZt/7vmIBcX2y9QDPte6u9P/CHHC/DjoWcCWuw5UY52aAq2RVElylvvRQYCL7mgWc1+JoHDoYQCwNe88AB0obH/OMYy21M/PU2zlgKXM/sdqjCwT5HFihGhnkTjk00UgxpjTZEZE5rbehK2uXKG/wOvBXOwqbapg3RY22Kv7PpvU0HbobXNq3bOy3Subf1H46K77fTIhxCH5MctT/sOtY8uLG55cSwJwwuLhyT8DK0EyjkmmO2DO76evt3XSu/DBoIN2TI2ROqjQfQv2+Ty2WY0mPUx/3RJL+VR7NvWIUfVrQI1LTekavHK3JVwagvXAATQFpd3jPpbZ40RnvVMePO/hpyqVj09ZI2xLcaCqtXgCIrJBPmElJrQEgDGzStLuwnY0UtZBoyk3aH5Blqk3gZWwIJWY5xsvV6iT58LQ+vXlQDLAjtINbFaxCtwnKeNOd9faB3UgvQ4FPT2R4lbk15hdpycwX/lAoIZOgDgTIHOPSoxoY9/rA1yC2FfMhl5mlnSDLOBHbyP665sZcMj+nroGEstdSPdt4+diJfdOfO0bFeSSf2qF7NBFGvgBiDeXEYIvwhOHtEz0VfhpzbPeMXuRWwvOCYozAhx84kau89UmLoyr/gqbbIV3AvQ3JereP605BUCkOY0CAFth648gXopjDlhkOoj6NSUrkx4xzakj2haD0LlPgaOhIFueWGFRzBsBx71rBbOq9L1SPo/dNOccNTqnRQCwolDkaVrBzFoBHjj63PGt9VG6rbU9bIaro6x11uHDglzAurHi44eiY3dl8BuHPT+Adwagc0OoeJqcW27SGsmVmBkOK9sz2bloJZNsxc7jCbd5zs8JtrcPydygx/PmmIxOqx3pA06/AodyQNGgCOccLRGFTzGsHCppzpVUitHAoIKMDIgtFBHDp7bxYi65XUCJVsv8XKFpmvN6QbuJUZW2yu6eOn6oZzMvhoUzYN530ycXM2ns8cZjWyS45hL1NfhS4IQ89j7gz4YP5bATohje/mkqSbROGy70V1z8XqElIlH9GF0GuxDatKtCdULubk2lHDGIvkTodOXPg7XGc6ZTwewj1qt4zE4MRu0YgzRZCIj71JanRg+LyOp51R7BvwE93PMZLfUZC/zzksWwzi68Z7QqUenUt472mzF+rtBkyEpb7yjU5Mh3d9GVndAn9aaUjrXaidBKgUC7ZMQnw13qrkoX4JomwgBHRFhDMF9Ysd2lag0Qe1Erx8/5qHY91S+aDZzFzXksA59m17oKFg9LQluwf36JmLdS82EdMostlL0T4Fe7FVmSlem9Onp2nShO8stC7T7x80pj6H3fcclJ7Da9So4LxQoBEEeFfrQ4OelYfnjgfO9fzVDHHdPc2CSdvCezl+7viOuHghIcnQ0V17CEEKvZK7ZdvYHUTl02dGJKVRnLUw1FE1KQkdNeDPZLj7UZ9q3ebZ9NRVLDiq8ha+OWbaEaQnqlnYfOK9WEMV20Q0ql6jsZ2oypfm1N53bhX1n/pqfEHpzS7uKT4qtM0EpSLLps7G2tF6H1oeuKWVFCzaD/Wfio3JeWKPKn5Cbsh2QFzffQZK/IaVxiBwZsNdydGsZOZRVCMhvAiAygwPu2BizerbmbybW3F5khKNWVJ+Q4tQinq8ObKjjboYV35my417P8VF+Q0vSNGl/UtFhAsQAhrQkiPfQGbRxbblndc3X3oCWUdsGzOPxid8Ssf1682XRky+a5f6Fx1LVesCKVswmjisuTXj1id2NF/V23KSNZVYYTigze2pgENfgjh9yA36esnJfHe+XbL7XYtzZyPs7neagczBD3SMZVb2jft5vVyO8dHeHONDr8b5DN+8hgJVeeCrpYiSDVBOdJUdexDgv4FQHd8WFH0LGdlcekU5Bdb3KSzC6RRiyhI1yQvuzJN/p8MT4dVxEGmNfzQjPedWwotpfG2gDNdf9Kjf0hkvCaiiasJ53cPlN0y+s07+XwAAAP//xqWRdw==" }