Skip to content

Commit

Permalink
add huaweicloudlogsreceiver skelethon
Browse files Browse the repository at this point in the history
  • Loading branch information
narcis.gemene committed Sep 11, 2024
1 parent a7e578e commit 525a329
Show file tree
Hide file tree
Showing 29 changed files with 1,949 additions and 13 deletions.
1 change: 1 addition & 0 deletions internal/huawei/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../../Makefile.Common
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver/internal"
package huawei // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/huawei"

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package internal
package huawei

import (
"context"
Expand Down
16 changes: 16 additions & 0 deletions internal/huawei/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module github.com/open-telemetry/opentelemetry-collector-contrib/internal/huawei

go 1.22.3

require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
18 changes: 18 additions & 0 deletions internal/huawei/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions receiver/huaweicloudcesreceiver/go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
module github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver

go 1.22.0

toolchain go1.22.3
go 1.22.3

require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.110
github.com/open-telemetry/opentelemetry-collector-contrib/internal/huawei v0.108.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.108.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.107.0
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -88,6 +87,8 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/huawei => ./../../internal/huawei

replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil => ../../pkg/pdatautil

replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest
Expand Down
5 changes: 3 additions & 2 deletions receiver/huaweicloudcesreceiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"go.opentelemetry.io/collector/receiver"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/huawei"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver/internal"
)

Expand Down Expand Up @@ -155,7 +156,7 @@ func (rcvr *cesReceiver) pollMetricsAndConsume(ctx context.Context) error {
}

func (rcvr *cesReceiver) listMetricDefinitions(ctx context.Context) ([]model.MetricInfoList, error) {
response, err := internal.MakeAPICallWithRetry(
response, err := huawei.MakeAPICallWithRetry(
ctx,
rcvr.shutdownChan,
rcvr.logger,
Expand Down Expand Up @@ -239,7 +240,7 @@ func (rcvr *cesReceiver) listDataPoints(ctx context.Context, metricDefinitions [
}

func (rcvr *cesReceiver) listDataPointsForMetric(ctx context.Context, from, to time.Time, infoList model.MetricInfoList) (*model.ShowMetricDataResponse, error) {
return internal.MakeAPICallWithRetry(
return huawei.MakeAPICallWithRetry(
ctx,
rcvr.shutdownChan,
rcvr.logger,
Expand Down
12 changes: 6 additions & 6 deletions receiver/huaweicloudcesreceiver/receiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestListMetricDefinitionsFailure(t *testing.T) {
metrics, err := receiver.listMetricDefinitions(context.Background())

assert.Error(t, err)
assert.Len(t, metrics, 0)
assert.Empty(t, metrics)
assert.Equal(t, "failed to list metrics", err.Error())
mockCes.AssertExpectations(t)
}
Expand Down Expand Up @@ -277,7 +277,7 @@ func TestStartReadingMetrics(t *testing.T) {
func TestCreateHTTPConfigNoVerifySSL(t *testing.T) {
cfg, err := createHTTPConfig(HuaweiSessionConfig{NoVerifySSL: true})
require.NoError(t, err)
assert.Equal(t, cfg.IgnoreSSLVerification, true)
assert.True(t, cfg.IgnoreSSLVerification)
}

func TestCreateHTTPConfigWithProxy(t *testing.T) {
Expand All @@ -289,9 +289,9 @@ func TestCreateHTTPConfigWithProxy(t *testing.T) {
SecretKey: "secret",
})
require.NoError(t, err)
assert.Equal(t, cfg.HttpProxy.Schema, "https")
assert.Equal(t, cfg.HttpProxy.Host, "127.0.0.1")
assert.Equal(t, cfg.HttpProxy.Port, 8888)
assert.Equal(t, cfg.IgnoreSSLVerification, false)
assert.Equal(t, "https", cfg.HttpProxy.Schema)
assert.Equal(t, "127.0.0.1", cfg.HttpProxy.Host)
assert.Equal(t, 8888, cfg.HttpProxy.Port)
assert.False(t, cfg.IgnoreSSLVerification)

}
1 change: 1 addition & 0 deletions receiver/huaweicloudlogsreceiver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../Makefile.Common
205 changes: 205 additions & 0 deletions receiver/huaweicloudlogsreceiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# Huawei Cloud CES Receiver

<!-- status autogenerated section -->
| Status | |
| ------------- |-----------|
| Stability | [development]: logs |
| Distributions | [] |
| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fhuaweicloudlogs%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Areceiver%2Fhuaweicloudlogs) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fhuaweicloudlogs%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aclosed+is%3Aissue+label%3Areceiver%2Fhuaweicloudlogs) |
| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@heitorganzeli](https://www.github.com/heitorganzeli), [@narcis96](https://www.github.com/narcis96) |

[development]: https://github.com/open-telemetry/opentelemetry-collector#development
<!-- end autogenerated section -->

This receiver contains the implementation of the Huawei Cloud [Log Tank Service](https://www.huaweicloud.com/intl/en-us/product/lts.html) (LTS) receiver for the OpenTelemetry Collector. The receiver collects logs from Huawei Cloud's LTS service and sends them to the OpenTelemetry Collector for processing and exporting.

## Configuration

The following settings are required:

- `project_id`: The ID of the project in Huawei Cloud. This is used to identify which project's logs are to be collected. See [Obtaining a Project ID](https://support.huaweicloud.com/intl/en-us/devg-apisign/api-sign-provide-proid.html).

- `region_id`: The ID of the Huawei Cloud region from which logs are collected. For example, `eu-west-101`. The full list of the available regions can be found [here](https://pkg.go.dev/github.com/huaweicloud/[email protected]/services/lts/v2/region).

- `log_group_id`: A string indicating the ID of the log group.

- `log_stream_id`: A string indicating the ID of the log stream. See [Obtaining Log Group and Log Stream IDs](https://support.huaweicloud.com/intl/en-us/api-lts/lts_api_0006.html#section1).

- `no_verify_ssl`: A boolean flag indicating whether SSL verification should be disabled. Set to True to disable SSL verification.

- `access_key`: The access key needed for LTS authentification. Check `Huawei Cloud SDK Authentication Setup` section for more details.

- `secret_key`: The secret key needed for LTS authentification. Check `Huawei Cloud SDK Authentication Setup` section for more details.

The following settings are optional:

- `initial_delay`: The delay before the first collection of logs begins. This is a duration field, such as 5s for 5 seconds.

- `collection_interval` (default = `60s`): This is the interval at which this receiver collects logs. This value must be a string readable by Golang's [time.ParseDuration](https://pkg.go.dev/time#ParseDuration). Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. We recommend a polling interval of at least one minute.

- `retry_on_failure`: The following configurations can be used to control the retry policy of the LTS client. The default values are suitable for most deployment scenarios.
- `enabled` (default true)
- `initial_interval` (default 100ms)
- `max_interval` (default 1s)
- `max_elapsed_time` (default 15s)
- `randomization_factor` (default 0.5)
- `multiplier` (default 1.5)

### Example Configuration

```yaml
receivers:
huaweicloudlogsreceiver:
collection_interval: 3h
initial_delay: 5s
access_key: ${env:HUAWEICLOUD_SDK_AK}
secret_key: ${env:HUAWEICLOUD_SDK_SK}
project_id: project_1
region_id: eu-west-101
log_group_id: test-group-id
log_stream_id: test-stream-id
no_verify_ssl: True
```
The full list of settings exposed for this receiver are documented [here](./config.go).
### Huawei Cloud SDK Authentication Setup
To ensure secure authentication, the Access Key (AK) and Secret Key (SK) used by the Huawei Cloud SDK must be stored in environment variables. See [Obtaining an AK/SK](https://support.huaweicloud.com/intl/en-us/devg-apisign/api-sign-provide-aksk.html).
Before running the application, you need to set the environment variables `HUAWEICLOUD_SDK_AK` and `HUAWEICLOUD_SDK_SK` in your local environment. Here’s how you can do it:

1. Open your terminal.
2. Set the environment variables by executing the following commands:

```sh
export HUAWEICLOUD_SDK_AK=your-access-key
export HUAWEICLOUD_SDK_SK=your-secret-key
```

3. Verify that the variables are set correctly:

```sh
echo $HUAWEICLOUD_SDK_AK
echo $HUAWEICLOUD_SDK_SK
```

## Error handling
If you encounter any LTS errors, please refer to the [Huawei Cloud Error Codes](https://support.huaweicloud.com/intl/en-us/ae-ad-1-api-lts/lts_api_0021.html).

## Converting LTS Log Representation to OpenTelemetry Log Representation

| Source Field | Target Field | Description |
|---------------------------|----------------------------------------------------|---------------------------------------------------------------------------------------------------|
| **Log Content (timestamp)** | `logRecord.observedTimestamp` | The timestamp extracted from the log content. It follows the layout `"2006-01-02/15:04:05"`. Converted to Unix time in nanoseconds. |
| **Log Content (body)** | `logRecord.body` | The main content of the log. Stored as a string in the OTLP log body. |
| **Labels (key)** | `logRecord.attributes` | Each label from the LTS log is converted to an attribute in the OTLP log, where the label's key is used as the attribute's key. |
| **Labels (value)** | `logRecord.attributes` | The corresponding value of each LTS log label key is stored as the attribute's value. |
| **Line Number** | `logRecord.attributes.lineNum` | The line number from the LTS log, if available. Stored as an attribute with the key `lineNum`. |
| **Project ID** | `resource.attributes.project.id` | The project ID used in the configuration file of the receiver.. |
| **Region ID** | `resource.attributes.region.id` | The region id used in the configuration file of the receiver. |
| **Group ID** | `resource.attributes.group.id` | The log group id used in the configuration file of the receiver. |
| **Stream ID** | `resource.attributes.stream.id` | The log stream id used in the configuration file of the receiver. |
| *N/A* | `resource.attributes.cloud.provider` | Set to `"huawei_cloud"` as the cloud provider. |
| *N/A* | `scopeLogs.scope.name` | Set to `"huawei_cloud_lts"` as the scope name. |
| *N/A* | `scopeLogs.scope.version` | Set to `"v2"` as the scope version. |

This mapping ensures that logs from Huawei Cloud's LTS can be seamlessly integrated into systems using the OpenTelemetry Protocol for observability.


### Notes

- The `timestamp` field in the source is converted from milliseconds to nanoseconds in the target field.
- Some fields are added in the target format with constant values to provide additional context and metadata.

### Example:

```json
[
{
"content": "2020-07-25/14:40:00 this logis Error NO 2",
"line_num": "123",
"labels": {
"hostIP": "192.168.0.156",
"hostId": "9787ef31-f171-4eff-ba71-72d580f11f60",
"podName": "default_procname",
"clusterId": "CONFIG_FILE",
"nameSpace":"CONFIG_FILE",
"category": "LTS",
}
},
{
"content": "2020-07-25/14:50:00 this logis Error NO 3",
"line_num": "456",
"labels": {
"hostIP": "192.168.0.156",
"hostId": "9787ef31-f171-4eff-ba71-72d580f11f60",
"podName": "default_procname",
"clusterId": "CONFIG_FILE",
"nameSpace":"CONFIG_FILE",
"category": "LTS",
}
},
]
```

converts to

```json
{
"resourceLogs": [
{
"resource": {
"attributes": {
"cloud.provider": "huawei_cloud",
"project.id": "project1",
"region.id": "region1",
"group.id": "group1",
"stream.id":"stream1"
},
"scopeLogs": [
{
"scope": {
"name": "huawei_cloud_lts",
"version": "v2"
},
"logRecords": [
{
"observedTimeUnixNano": "1595688000000000000",
"body": {
"stringValue": "2020-07-25/14:40:00 this log is Error NO 2"
},
"attributes": {
"hostIP": "192.168.0.156",
"hostId": "9787ef31-f171-4eff-ba71-72d580f11f60",
"podName": "default_procname",
"clusterId": "CONFIG_FILE",
"nameSpace":"CONFIG_FILE",
"category": "LTS",
"lineNum": "123"
},
},
{
"observedTimeUnixNano": "1595688600000000000",
"body": {
"stringValue": "2020-07-25/14:50:00 this log is Error NO 3"
},
"attributes": {
"hostIP": "192.168.0.156",
"hostId": "9787ef31-f171-4eff-ba71-72d580f11f60",
"podName": "default_procname",
"clusterId": "CONFIG_FILE",
"nameSpace":"CONFIG_FILE",
"category": "LTS",
"lineNum": "456"
},
}
]
}
]
}
}
]
}
```
Loading

0 comments on commit 525a329

Please sign in to comment.