
Huawei Cloud Obs Stats
- 94 installs
- 19 repo stars
- Updated July 31, 2026
- huaweicloud/huaweicloud-skills
Query Huawei Cloud OBS statistics: list buckets with capacity and object counts, and download traffic and request counts with month-over-month comparison.
About
Queries Huawei Cloud OBS statistics including bucket capacity and object counts, extranet/intranet download traffic, and total requests with month-over-month comparison. A developer uses it to review storage usage and traffic trends, with all delete operations prohibited.
- Bucket capacity, object counts, traffic, and request stats
- Month-over-month comparison; delete operations forbidden
Huawei Cloud Obs Stats by the numbers
- 94 all-time installs (skills.sh)
- +14 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #572 of 1,042 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/huaweicloud/huaweicloud-skills --skill huawei-cloud-obs-statsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 94 |
|---|---|
| repo stars | ★ 19 |
| Last updated | July 31, 2026 |
| Repository | huaweicloud/huaweicloud-skills ↗ |
What it does
Query Huawei Cloud OBS statistics: list buckets with capacity and object counts, and download traffic and request counts with month-over-month comparison.
Files
Huawei Cloud OBS Statistics Skill
Overview
Query Huawei Cloud OBS (Object Storage Service) statistics: list buckets with capacity and object counts, query extranet/intranet download traffic with month-over-month comparison, and query total requests with month-over-month comparison.
⛔ Prohibited Operations (Security Constraints)
This skill strictly forbids the following delete operations, regardless of user requests:
| Prohibited Operation | API/Command | Reason |
|---|---|---|
| ❌ Delete bucket | DeleteBucket / obsutil rm -bucket | Irreversible; destroys the entire bucket and all objects |
| ❌ Delete object | DeleteObject / obsutil rm | Irreversible; deleted objects cannot be recovered (unless versioning is enabled) |
| ❌ Batch delete objects | DeleteObjects / obsutil rm -r | Irreversible; batch deletion has a wide impact |
| ❌ Empty bucket | obsutil rm -bucket -r | Irreversible; removes all objects in the bucket |
If a user requests a delete operation, you must refuse and inform:
"Per security constraints, this skill does not allow delete operations (delete bucket/object/batch delete/empty bucket). Please use the Huawei Cloud OBS console or obsutil manually."
Architecture
Huawei Cloud OBS Statistics
├── ListBucketsWithStats (List buckets with capacity and object counts)
├── GetTraffic (Query extranet/intranet download traffic with MoM comparison)
└── GetRequests (Query total requests with MoM comparison)Prerequisites
Prerequisite check: Huawei Cloud CLI (hcloud / KooCLI) >= 3.2.0 required
Run hcloud version to verify version >= 3.2.0. If not installed or version is too low,see references/cli-installation-guide.md for installation guide.
hcloud versionPrerequisite check: obsutil >= 5.5.0 required (for OBS bucket listing)
The hcloud OBS module uses obsutil under the hood. Bucket listing requires the obsutil CLI tool.
Run obsutil version to verify version >= 5.5.0. If not installed,see references/cli-installation-guide.md for installation guide.
obsutil versionPrerequisite check: obsutil credential configuration required
>
The hcloud OBS module uses obsutil under the hood, which requires separate AK/SK and Endpoint configuration.
Before performing OBS operations, you must check whether obsutil credentials are configured:
>
```bash
hcloud obs ls -limit=1
```
>
If the response is `Please set ak, sk and endpoint in the configuration file!` or `InvalidAccessKeyId`, obsutil credentials are not configured.
>
Resolution: Provide the following example command and have the user configure it in their terminal (do not ask the user to provide AK/SK directly in the conversation):
>
```
obsutil credentials are not configured. Please run the following command in your terminal to configure (AK/SK can be obtained from the Huawei Cloud console "My Credentials" page):
>
hcloud obs config -i=<YourAK> -k=<YourSK> -e=obs.<Region>.myhuaweicloud.com
>
Example (Guangzhou region):
hcloud obs config -i=<YourAK> -k=<YourSK> -e=obs.cn-south-1.myhuaweicloud.com
>
Common Endpoints:
cn-north-4 → obs.cn-north-4.myhuaweicloud.com
cn-east-3 → obs.cn-east-3.myhuaweicloud.com
cn-south-1 → obs.cn-south-1.myhuaweicloud.com
cn-southwest-2 → obs.cn-southwest-2.myhuaweicloud.com
>
Retry after configuration is complete.
```
>
Prohibited actions:
- ❌ Do not ask the user to provide AK/SK directly in the conversation
- ❌ Do not extract AK/SK from hcloud config files (credentials are encrypted and cannot be used directly)
- ❌ Do not skip the credential check before performing OBS operations
⚠️ hcloud parameter format requirements
>
hcloud (KooCLI) all parameters must use the `--param=value` format (connected with equals sign); space-separated format is not supported.
>
✅ Correct: hcloud OBS ListBuckets --region=cn-south-1>
❌ Incorrect: hcloud OBS ListBuckets --region cn-south-1[Conditional] CLI User-Agent — hcloud OBS module commands may include a User-Agent header, but the CES module does not support this parameter:
- ✅ OBS module:
hcloud obs ls - ❌ CES module:
hcloud CES ShowMetricDatadoes not support--User-Agent; appending it causes "Invalid parameter: User-Agent"
---
Authentication
Prerequisite check: Huawei Cloud credentials required
Security rules (must be followed):
- Prohibited from reading, echoing, or printing AK/SK values
- Prohibited from asking the user to input AK/SK directly in the conversation
- Prohibited from using hcloud configure set to pass plaintext credential values- Prohibited from accepting AK/SK directly provided by the user in the conversation
- Only allowed to read credentials from environment variables or configured CLI config files
>
⚠️ Important: Handling user-provided credentials
>
If a user attempts to provide AK/SK directly (e.g., "my AK is xxx, SK is yyy"):
1. Stop immediately - Do not execute any commands
2. Politely refuse and return the following message:
```
For account security, please do not provide Huawei Cloud Access Key ID and Access Key Secret directly in the conversation.
>
Please use one of the following secure methods to configure credentials:
>
Method 1: Interactive configuration (recommended)
hcloud configure
# Enter AK/SK as prompted; credentials will be securely stored in a local config file
>
Method 2: Environment variable configuration
export HUAWEICLOUD_SDK_AK=<your-access-key-id>
export HUAWEICLOUD_SDK_SK=<your-access-key-secret>
>
After configuration is complete, please retry your request.
```
3. Do not continue executing any Huawei Cloud operations until credentials are configured
>
Check CLI configuration:
```bash
hcloud configure list
```
Check whether the output contains valid configuration (AK/SK, IAM, etc.).
>
If no valid credentials exist, stop here.
---
IAM Permission Policies
Ensure the IAM user has the required permissions. See references/iam-policies.md for details.
Minimum required permissions:
obs:bucket:list— List bucketsobs:bucket:get— Get bucket attributes (capacity, object count)obs:object:get— Read object informationces:metric:get— Query CES monitoring metrics (traffic, request count)
---
Core Workflows
Task 1: List Buckets with Capacity and Object Counts
List buckets via obsutil, then query bucket capacity and object count using CES capacity metrics or OBS API.
📄 Detailed steps → references/task-list-buckets-with-stats.md
Task 2: Query Extranet/Intranet Download Traffic (with MoM Comparison)
Query download traffic (extranet + intranet) via CES ShowMetricData, with month-over-month comparison.
📄 Detailed steps → references/task-query-traffic.md
Task 3: Query Total Requests (with MoM Comparison)
Query total requests (sum of GET/PUT/POST/DELETE/HEAD) via CES ShowMetricData, with month-over-month comparison.
📄 Detailed steps → references/task-query-requests.md
---
Core Commands
| Command | Description |
|---|---|
hcloud obs ls | List all buckets (obsutil mode); filter by region via grep |
hcloud CES ShowMetricData --region=<R> --namespace=SYS.OBS --metric_name=<M> --dim.0=bucket_name,<B> --period=86400 --filter=<F> --from=<ms> --to=<ms> | Query CES metric data |
hcloud OBS GetBucketStorageInfo --region=<R> --bucket=<B> | Get bucket capacity & object count (may not be supported; fallback: obsutil ls obs://<B> -limit=0 -s) |
| `python3 scripts/obs_traffic_stats.py --region <R> --bucket <B> (--period <P> \ | --from <D> --to <D>) [--direction download\ |
| `python3 scripts/obs_request_stats.py --region <R> --bucket <B> (--period <P> \ | --from <D> --to <D>) [--include-errors]` |
⚠️ CES `ShowMetricData` does not support `--User-Agent`; appending it causes errors.
Common CES metrics:
>
| Metric |--metric_name|--filter|
|--------|----------------|------------|
| Bucket capacity |capacity_total|average|
| Extranet download traffic |download_traffic_extranet|sum|
| Intranet download traffic |download_traffic_intranet|sum|
| GET / PUT / POST / DELETE / HEAD requests |get_request_count/put_request_count/post_request_count/delete_request_count/head_request_count|sum|
---
Parameter Confirmation
Before executing any task, the following parameters must be confirmed with the user. Guessing is prohibited.
|| Parameter | Required/Optional | Description | Default || || ----------- | ------------------ | ------------- | --------- || || --region | Required | Huawei Cloud region (e.g., cn-south-1, cn-north-4); must be explicitly provided by the user | - || || Bucket name | Required | OBS bucket name; dimension format: --dim.0=bucket_name,<BucketName> | - || || Time range | Required | Must precisely match user's wording: "this month" ≠ "last 30 days" (see table below) | - || || obsutil credentials | Required | Check via hcloud obs ls -limit=1 before any OBS operation | - || || --direction | Optional | Traffic direction: download / upload / both | download || || --include-errors | Optional | Also query 4xx/5xx error request counts | false ||
Time range disambiguation:
>
| User's wording | Time range |
|---------|------|
| "this month" | 1st of current month 00:00:00 ~ now |
| "last 30 days" / "past month" | now - 30 days ~ now |
| "last month" | 1st of last month 00:00:00 ~ last day of last month 23:59:59 |
| Specific date range | User-specified start and end times |
---
Script Tools
This skill provides the following Python scripts that encapsulate best practices for traffic and request statistics:
obs_traffic_stats.py — Download/Upload Traffic Statistics
# Last 30 days download traffic
python3 scripts/obs_traffic_stats.py --region cn-south-1 --bucket obs-60030508 --period last_30d
# This month download + upload traffic
python3 scripts/obs_traffic_stats.py --region cn-south-1 --bucket obs-60030508 --period this_month --direction both
# Custom date range
python3 scripts/obs_traffic_stats.py --region cn-south-1 --bucket obs-60030508 --from 2026-04-20 --to 2026-05-20obs_request_stats.py — Total Request Statistics
# Last 30 days request count
python3 scripts/obs_request_stats.py --region cn-south-1 --bucket obs-60030508 --period last_30d
# This month request count (with 4xx/5xx error stats)
python3 scripts/obs_request_stats.py --region cn-south-1 --bucket obs-60030508 --period this_month --include-errors
# Custom date range
python3 scripts/obs_request_stats.py --region cn-south-1 --bucket obs-60030508 --from 2026-04-20 --to 2026-05-20The scripts incorporate key lessons learned: traffic vs. bandwidth metrics, hcloud dimension parameter format, precise time range matching, OBS lacking a single request_count metric, etc.
---
Verification Method
See references/verification-method.md for details.
Quick validation:
# Check OBS bucket list (using obsutil)
hcloud obs ls -limit=1
# Check obsutil configuration
obsutil ls -limit=1
# Validate traffic stats script
python3 scripts/obs_traffic_stats.py --region cn-south-1 --bucket <BucketName> --period last_30d
# Validate request stats script
python3 scripts/obs_request_stats.py --region cn-south-1 --bucket <BucketName> --period last_30d---
References
| Document | Description |
|---|---|
| task-list-buckets-with-stats.md | Task 1: List buckets with capacity and object counts |
| task-query-traffic.md | Task 2: Query download traffic with MoM |
| task-query-requests.md | Task 3: Query total requests with MoM |
| related-apis.md | API and CLI command details |
| iam-policies.md | IAM permission policies |
| obs-metrics.md | OBS CES monitoring metrics reference |
| verification-method.md | Verification steps |
| acceptance-criteria.md | Correct/error pattern comparison |
| cli-installation-guide.md | CLI installation guide |
| troubleshooting.md | Troubleshooting and practical experience |
| obs_traffic_stats.py | Traffic statistics script |
| obs_request_stats.py | Request statistics script |
Acceptance Criteria: huawei-cloud-obs-stats
Scenario: Huawei Cloud OBS Object Storage Statistics Purpose: Skill test acceptance criteria
Table of Contents
- Correct CLI Command Patterns
- Correct SDK Code Patterns
- Response Validation Criteria
- Security Criteria
- Month-over-Month Calculation Criteria
- References
---
Correct CLI Command Patterns
0. Parameter Format — hcloud must use equals sign format
✅ Correct
hcloud obs ls
hcloud CES ShowMetricData --region=cn-south-1 --namespace=SYS.OBS --metric_name=download_traffic_extranet
hcloud version❌ Incorrect
hcloud obs ls --region cn-south-1 # Incorrect: obsutil mode parameters not applicable
hcloud --version # Incorrect: hcloud does not support --version; use hcloud version⚠️ Key: hcloud OBS module is obsutil
>
The hcloud CLI OBS module directly maps to obsutil commands; use lowercasehcloud obs, nothcloud OBS.
To list buckets, usehcloud obs ls; there is noListAllMyBucketsTypecommand.
1. OBS Commands — Use obsutil mode
✅ Correct
hcloud obs ls # List all buckets
hcloud obs ls obs://my-bucket -s # List objects in bucket
hcloud obs stat obs://my-bucket # View bucket attributes❌ Incorrect
hcloud OBS ListAllMyBucketsType # Incorrect: This command does not exist
hcloud obs list-buckets # Incorrect: obsutil command is ls2. CES Commands — Query monitoring metrics
✅ Correct
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,my-bucket \
--period=86400 \
--filter=sum \
--from=1746057600000 \
--to=1747612800000❌ Incorrect
hcloud ces ShowMetricData ... # Incorrect: CES product name must be uppercase
hcloud CES ShowMetricData \
--namespace=OBS # Incorrect: Should be SYS.OBS
hcloud CES ShowMetricData \
--dimensions.0.name=bucket_name \
--dimensions.0.value=my-bucket # Incorrect: hcloud uses --dim.0=key,value format3. CES Dimension Parameter Format
✅ Correct
--dim.0=bucket_name,my-bucket❌ Incorrect
--dimensions.0.name=bucket_name --dimensions.0.value=my-bucket # Incorrect: SDK format, not supported by hcloud
--dim.0=bucket,my-bucket # Incorrect: Dimension key should be bucket_name4. CES Namespace and Metric Names
✅ Correct
--namespace=SYS.OBS
--metric_name=download_traffic_extranet
--metric_name=download_traffic_intranet
--metric_name=get_request_count
--metric_name=put_request_count
--dim.0=bucket_name,my-bucket❌ Incorrect
--namespace=OBS # Incorrect: Should be SYS.OBS
--namespace=SYS.OBJECT_STORAGE # Incorrect: Should be SYS.OBS
--metric_name=downloadBytes # Incorrect: Should be download_traffic_extranet (snake_case)
--metric_name=download_bytes # Incorrect: This is a bandwidth metric (Bytes/s), not a traffic metric (Bytes)
--metric_name=request_count # Incorrect: This metric does not exist in CES for OBS
--dim.0=bucketName,my-bucket # Incorrect: Dimension key should be bucket_name
--dim.0=bucket,my-bucket # Incorrect: Dimension key should be bucket_name5. Time Ranges — Millisecond Timestamps
✅ Correct
--from=1746057600000 # Millisecond timestamp
--to=1747612800000 # Millisecond timestamp❌ Incorrect
--from=1746057600 # Incorrect: Second-level timestamp; CES requires millisecond-level (13 digits)
--from=2025-05-01 # Incorrect: CES requires Unix timestamp, not date string6. CES ShowMetricData — User-Agent Not Supported
✅ Correct
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,my-bucket \
--period=86400 \
--filter=sum \
--from=1746057600000 \
--to=1747612800000❌ Incorrect
hcloud CES ShowMetricData \
--User-Agent=HuaweiCloud-Agent-Skills/huawei-cloud-obs-stats \
... # Incorrect: CES ShowMetricData does not support --User-Agent parameter---
Correct SDK Code Patterns
1. Import Patterns
✅ Correct
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkobs.v1.client import ObsClient
from huaweicloudsdkces.v1.client import CesClient
from huaweicloudsdkces.v1.region.ces_region import CesRegion❌ Incorrect
from huaweicloudsdkobs import Client # Incorrect: Missing correct module path2. Authentication — Must use BasicCredentials; hardcoded AK/SK prohibited
✅ Correct
from huaweicloudsdkcore.auth.credentials import BasicCredentials
credentials = BasicCredentials() \
.with_ak(os.getenv("HUAWEICLOUD_SDK_AK")) \
.with_sk(os.getenv("HUAWEICLOUD_SDK_SK")) \
.with_project_id(os.getenv("HUAWEICLOUD_SDK_PROJECT_ID"))❌ Incorrect
credentials = BasicCredentials() \
.with_ak("XXXXXXXXXX") # Prohibited: Hardcoded AK
.with_sk("YYYYYYYYYY") # Prohibited: Hardcoded SK3. OBS Client Initialization
✅ Correct
from obs import ObsClient
obs_client = ObsClient(
access_key_id=os.getenv("HUAWEICLOUD_SDK_AK"),
secret_access_key=os.getenv("HUAWEICLOUD_SDK_SK"),
server='obs.cn-south-1.myhuaweicloud.com'
)❌ Incorrect
obs_client = ObsClient(
access_key_id="XXXXXXXXXX", # Prohibited: Hardcoded AK
secret_access_key="YYYYYYYYYY", # Prohibited: Hardcoded SK
server='obs.cn-south-1.myhuaweicloud.com'
)---
Response Validation Criteria
obs ls response (list buckets)
✅ Must include:
- Bucket name list
- Region information for each bucket
obs stat response (bucket attributes)
✅ Must include:
size- Total size of objects in the bucket (bytes)objectNumber- Total number of objects in the bucket
CES ShowMetricData response
✅ Must include:
datapointsarray, each containingtimestamp,unit, and an aggregate value (sum/average/max/min)metric_name(string)
---
Security Criteria
✅ Correct Security Practices
1. Use hcloud configure list to verify credentials (do not echo AK/SK) 2. SDK uses BasicCredentials to read from environment variables 3. Sensitive data uses environment variables 4. obsutil credentials configured securely via obsutil config
❌ Incorrect Security Practices
1. Hardcode access keys in code or commands 2. Print or echo credential values 3. Use hcloud configure set to pass plaintext credentials in automation scripts 4. Ask the user to provide AK/SK directly in the conversation
⛔ Prohibited Operations (Security Constraints)
The following delete operations are strictly forbidden, regardless of user requests:
❌ Absolutely Prohibited
hcloud obs rm obs://my-bucket -r # Prohibited: Recursively delete all objects in bucket
hcloud obs rm obs://my-bucket # Prohibited: Delete bucket✅ Correct: Refuse delete request and direct to console
"Per security constraints, this skill does not allow delete operations (delete bucket/object/batch delete/empty bucket). Please use the Huawei Cloud OBS console or obsutil manually."---
Month-over-Month Calculation Criteria
✅ Correct Calculation
MoM (%) = (Current Month Value - Last Month Value) / Last Month Value × 100%
Example:
Current month = 125.3 GB, Last month = 98.7 GB
MoM = (125.3 - 98.7) / 98.7 × 100% = +26.95%Special Case Handling
| Case | Correct Handling | Incorrect Handling |
|---|---|---|
| Last month=0, Current>0 | Display "New (last month was 0)" | ❌ Display +∞% |
| Last month=0, Current=0 | Display "N/A" | ❌ Display 0% |
| Last month>0, Current>0 | Calculate percentage, rounded to 2 decimal places | ❌ Integer truncation |
| Current<Last month | Display negative (e.g., -15.30%) | ❌ Display 0% |
---
References
CLI Installation Guide - Huawei Cloud OBS Object Storage Statistics
This skill requires two CLI tools: hcloud (KooCLI) and obsutil.
Table of Contents
- hcloud (KooCLI) Installation
- obsutil Installation
- Credential Configuration
- Verify Installation
- Troubleshooting
---
hcloud (KooCLI) Installation
macOS
# Install via Homebrew
brew install hcloudcli
# Or download directly
curl -O https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/hcloudcli/latest/hcloudcli-macos-amd64.tar.gz
tar -xzf hcloudcli-macos-amd64.tar.gz
chmod +x hcloud
sudo mv hcloud /usr/local/bin/Linux (x86_64)
curl -O https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/hcloudcli/latest/hcloudcli-linux-amd64.tar.gz
tar -xzf hcloudcli-linux-amd64.tar.gz
chmod +x hcloud
sudo mv hcloud /usr/local/bin/Linux (ARM64)
curl -O https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/hcloudcli/latest/hcloudcli-linux-arm64.tar.gz
tar -xzf hcloudcli-linux-arm64.tar.gz
chmod +x hcloud
sudo mv hcloud /usr/local/bin/Windows
# Download and extract
Invoke-WebRequest -Uri "https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/hcloudcli/latest/hcloudcli-windows-amd64.zip" -OutFile "hcloudcli.zip"
Expand-Archive hcloudcli.zip
# Add hcloud.exe to PATH---
obsutil Installation
macOS
curl -O https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_darwin_amd64.tar.gz
tar -xzf obsutil_darwin_amd64.tar.gz
chmod +x obsutil_darwin_amd64_*
sudo mv obsutil_darwin_amd64_*/obsutil /usr/local/bin/Linux (x86_64)
curl -O https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_linux_amd64.tar.gz
tar -xzf obsutil_linux_amd64.tar.gz
chmod +x obsutil_linux_amd64_*
sudo mv obsutil_linux_amd64_*/obsutil /usr/local/bin/Linux (ARM64)
curl -O https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_linux_arm64.tar.gz
tar -xzf obsutil_linux_arm64.tar.gz
chmod +x obsutil_linux_arm64_*
sudo mv obsutil_linux_arm64_*/obsutil /usr/local/bin/Windows
Invoke-WebRequest -Uri "https://obs-community-tool.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_windows_amd64.zip" -OutFile "obsutil.zip"
Expand-Archive obsutil.zip
# Add obsutil.exe to PATH---
Credential Configuration
hcloud Credential Configuration
Method 1: Interactive configuration (recommended)
hcloud configure
# Enter as prompted:
# - Region (e.g., cn-south-1)
# - AK (Access Key ID)
# - SK (Access Key Secret)Method 2: Environment variables
export HUAWEICLOUD_SDK_AK=<your-access-key-id>
export HUAWEICLOUD_SDK_SK=<your-access-key-secret>Method 3: Non-interactive configuration
hcloud configure set --cli-profile=default --region=cn-south-1 --access-key-id=<AK> --secret-access-key=<SK>⚠️ Security warning: Method 3 exposes AK/SK in command history; only use in secure environments.
obsutil Credential Configuration
obsutil config -ak=<AK> -sk=<SK> -e=obs.cn-south-1.myhuaweicloud.com⚠️ obsutil Endpoint format
>
OBS Endpoint format: obs.<region-id>.myhuaweicloud.com>
Common endpoints:
>
| Region | Endpoint |
|--------|----------|
| cn-north-1 | obs.cn-north-1.myhuaweicloud.com |
| cn-north-4 | obs.cn-north-4.myhuaweicloud.com |
| cn-east-2 | obs.cn-east-2.myhuaweicloud.com |
| cn-east-3 | obs.cn-east-3.myhuaweicloud.com |
| cn-south-1 | obs.cn-south-1.myhuaweicloud.com |
| ap-southeast-1 | obs.ap-southeast-1.myhuaweicloud.com |
---
Verify Installation
Verify hcloud
# Check version
hcloud version
# Expected: >= 3.2.0
# Test authentication
hcloud obs lsVerify obsutil
# Check version
obsutil version
# Expected: >= 5.5.0
# Test authentication (list buckets, limit 1)
obsutil ls -limit=1---
Troubleshooting
hcloud Common Issues
| Issue | Cause | Solution |
|---|---|---|
hcloud: command not found | Not installed or not in PATH | Install hcloud or add to PATH |
authentication failed | Invalid or expired credentials | Reconfigure credentials |
insufficient permissions | Insufficient IAM permissions | Add required IAM policies |
region not found | Incorrect region ID | Use the correct region ID |
obsutil Common Issues
| Issue | Cause | Solution |
|---|---|---|
obsutil: command not found | Not installed or not in PATH | Install obsutil or add to PATH |
Status code: 403 | AK/SK incorrect or insufficient permissions | Re-run obsutil config to configure credentials |
Status code: 404 | Bucket does not exist | Confirm bucket name is correct |
connection timeout | Network issue or incorrect endpoint | Check network connection and endpoint configuration |
---
Security Best Practices
1. Never provide AK/SK directly in conversation — always use interactive configuration or environment variables 2. Rotate AK/SK regularly — recommended every 90 days 3. Use IAM temporary credentials — prefer IAM agency delegation or temporary credentials 4. Least privilege principle — grant only the minimum required permissions 5. Audit logging — enable OBS bucket logging to record access requests 6. obsutil credential file permissions — ensure obsutil config file has 600 permissions
---
References
IAM Permission Policies - Huawei Cloud OBS Object Storage Statistics
IAM permission policies required for this skill.
Required Permissions Overview
| Operation | IAM Action (Legacy v3) | IAM Action (New v5) | Description |
|---|---|---|---|
| List buckets | obs:bucket:ListAllMyBuckets | obs:bucket:listAllMyBuckets | List all buckets in the current account |
| Get bucket storage info | obs:bucket:GetBucketStorageInfo | obs:bucket:getBucketStorageInfo | Get bucket capacity and object count |
| Get bucket attributes | obs:bucket:GetBucketMetadata | obs:bucket:getBucketMetadata | Get bucket metadata |
| List objects | obs:bucket:ListBucket | obs:bucket:listBucket | List objects in bucket |
| Query CES metrics | ces:metric:get | ces:metric:get | Query CES monitoring metrics |
---
Minimum Required Policy (JSON)
Legacy IAM (v3 API - Role and Policy Authorization)
{
"Version": "1.1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"obs:bucket:ListAllMyBuckets",
"obs:bucket:GetBucketStorageInfo",
"obs:bucket:GetBucketMetadata",
"obs:bucket:ListBucket",
"ces:metric:get"
]
}
]
}New IAM (v5 API - Identity Policy Authorization)
{
"Version": "5.0",
"Statement": [
{
"Effect": "Allow",
"Action": [
"obs:bucket:listAllMyBuckets",
"obs:bucket:getBucketStorageInfo",
"obs:bucket:getBucketMetadata",
"obs:bucket:listBucket",
"ces:metric:get"
],
"Resource": [
"OBS:*:*:bucket:*",
"CES:*:*:metric:*"
]
}
]
}---
Resource-Level Policy (Recommended)
Restrict to specific buckets for enhanced security:
{
"Version": "5.0",
"Statement": [
{
"Effect": "Allow",
"Action": [
"obs:bucket:listAllMyBuckets",
"obs:bucket:getBucketStorageInfo",
"obs:bucket:getBucketMetadata",
"obs:bucket:listBucket"
],
"Resource": [
"OBS:*:*:bucket:<BucketName>",
"OBS:*:*:object:<BucketName>/*"
]
},
{
"Effect": "Allow",
"Action": [
"ces:metric:get"
],
"Resource": [
"CES:*:*:metric:*"
]
}
]
}---
Read-Only Policy
For viewing bucket info and monitoring data only (no upload allowed):
{
"Version": "5.0",
"Statement": [
{
"Effect": "Allow",
"Action": [
"obs:bucket:listAllMyBuckets",
"obs:bucket:getBucketStorageInfo",
"obs:bucket:getBucketMetadata",
"obs:bucket:listBucket",
"ces:metric:get"
],
"Resource": [
"OBS:*:*:bucket:*",
"CES:*:*:metric:*"
]
}
]
}---
System Policies
Use Huawei Cloud pre-built system policies for simplified authorization:
| System Policy | Included Permissions | Use Case |
|---|---|---|
OBS ReadOnlyAccess | Bucket and object read-only | ✅ Recommended for this skill |
OBS Administrator | Full OBS permissions | ⚠️ Overly permissive, not recommended |
CES ReadOnlyAccess | CES read-only | View monitoring metrics |
Recommended combination: OBS ReadOnlyAccess + CES ReadOnlyAccess
⚠️ OBS ReadOnlyAccess notes
>
OBS ReadOnlyAccess includes bucket and object read-only permissions, which aligns with this skill's statistics-only scope.
This skill does not support upload or delete operations.
---
Bucket Policy Authorization
In addition to IAM policies, you can also authorize via Bucket Policy:
{
"Statement": [
{
"Effect": "Allow",
"Principal": {"ID": ["<IAMUserId>"]},
"Action": [
"obs:bucket:ListBucket",
"obs:bucket:GetBucketStorageInfo"
],
"Resource": [
"my-bucket",
"my-bucket/*"
]
}
]
}---
Policy Best Practices
1. Least privilege principle: Grant only the minimum required permissions; prefer resource-level policies 2. Read-only access: This skill only queries bucket info and monitoring data; policies should not include write or delete permissions 3. OBS ReadOnlyAccess recommended: Among system policies, OBS ReadOnlyAccess best matches this skill's requirements 4. CES data access: Querying monitoring metrics requires CES ReadOnlyAccess 5. Regular review: Periodically review IAM policies to ensure no excess permissions
---
References
OBS CES Monitoring Metrics Reference - Huawei Cloud OBS Object Storage Statistics
OBS monitoring metrics reported in CES (Cloud Eye Service), with namespace SYS.OBS.
Official documentation reference: https://support.huaweicloud.com/usermanual-obs/obs_03_0010.html
Namespace
SYS.OBS
Dimensions
| Dimension | Key | hcloud Parameter Format | Description |
|---|---|---|---|
| Bucket name | bucket_name | --dim.0=bucket_name,<BucketName> | OBS bucket name |
⚠️ hcloud CES dimension parameter format
>
hcloud CES ShowMetricData uses --dim.N=key,value format for dimension parameters:```bash
--dim.0=bucket_name,my-bucket
```
>
❌ Incorrect format (SDK/REST API format, not supported by hcloud):
```bash
--dimensions.0.name=bucket_name --dimensions.0.value=my-bucket
```
---
Traffic Metrics
⚠️ Key: Bandwidth metrics vs. Traffic metrics
>
- Traffic metrics (cumulative, unit: Bytes): can be summed directly for total bytes, must use these for traffic queries
- Bandwidth metrics (rate, unit: Bytes/s): must be multiplied by the aggregation period to convert to bytes, error-prone, prohibited for traffic queries
Traffic Metrics (Cumulative, Recommended)
| Metric Name | Metric ID | Unit | Description |
|---|---|---|---|
| Extranet download traffic | download_traffic_extranet | Bytes | Total extranet download object size (including CDN origin pull) |
| Intranet download traffic | download_traffic_intranet | Bytes | Total intranet download object size |
| Total download traffic | download_traffic | Bytes | Total download object size |
| Extranet upload traffic | upload_traffic_extranet | Bytes | Total extranet upload object size |
| Intranet upload traffic | upload_traffic_intranet | Bytes | Total intranet upload object size |
| Total upload traffic | upload_traffic | Bytes | Total upload object size |
| CDN origin pull traffic | cdn_traffic | Bytes | Total CDN origin pull request traffic |
Bandwidth Metrics (Rate, Avoid for Traffic Statistics)
| Metric Name | Metric ID | Unit | Description |
|---|---|---|---|
| Total download bandwidth | download_bytes | Bytes/s | Average download object bytes per second |
| Extranet download bandwidth | download_bytes_extranet | Bytes/s | Average extranet download bytes per second |
| Intranet download bandwidth | download_bytes_intranet | Bytes/s | Average intranet download bytes per second |
| Total upload bandwidth | upload_bytes | Bytes/s | Average upload object bytes per second |
| Extranet upload bandwidth | upload_bytes_extranet | Bytes/s | Average extranet upload bytes per second |
| Intranet upload bandwidth | upload_bytes_intranet | Bytes/s | Average intranet upload bytes per second |
⚠️ Traffic billing notes
>
- Extranet download traffic (download_traffic_extranet): billed item, extranet outbound traffic is charged per GB (including CDN origin pull)- Intranet download traffic (download_traffic_intranet): free, same-region/same-VPC intranet transfer is not charged- Extranet upload traffic (upload_traffic_extranet): free, extranet inbound traffic is not charged- Intranet upload traffic (upload_traffic_intranet): free---
Request Metrics
| Metric Name | Metric ID | Unit | Description |
|---|---|---|---|
| GET requests | get_request_count | Count | GET-type requests (GetObject, HeadObject, ListObjects, etc.) |
| PUT requests | put_request_count | Count | PUT-type requests (PutObject, CopyObject, etc.) |
| POST requests | post_request_count | Count | POST-type requests |
| HEAD requests | head_request_count | Count | HEAD-type requests |
| DELETE requests | delete_request_count | Count | DELETE-type requests |
| 4xx status codes | request_count_4xx | Count | Requests with 4xx server responses |
| 5xx status codes | request_count_5xx | Count | Requests with 5xx server responses |
| GET first byte latency | first_byte_latency | ms | GET request average first byte latency |
| Total TPS | request_count_per_second | Count/s | Requests per second |
⚠️ Note: OBS has no `request_count` metric
>
There is no OBS metric named request_count in CES. Total request count must be calculated by summing all request types:Total requests = get_request_count + put_request_count + post_request_count + head_request_count + delete_request_count>
Alternatively, use the TPS metric request_count_per_second (requests per second; requires multiplication by aggregation period for total count).⚠️ Request billing notes
>
- GET/HEAD requests: billed per 10,000 requests (lower price)
- PUT/POST/DELETE requests: billed per 10,000 requests (higher price, typically 10x GET price)
---
Capacity Metrics
| Metric Name | Metric ID | Unit | Description |
|---|---|---|---|
| Total storage usage | capacity_total | Bytes | Total storage occupied by all data |
| Standard storage usage | capacity_standard | Bytes | Storage occupied by standard storage data |
| Infrequent access storage | capacity_infrequent_access | Bytes | Storage occupied by infrequent access data |
| Archive storage | capacity_archive | Bytes | Storage occupied by archive data |
| Deep archive storage | capacity_deep_archive | Bytes | Storage occupied by deep archive data |
⚠️ Capacity metric collection notes
>
- CES capacity metrics are collected every 30 minutes, not real-time
- For exact bucket capacity and object count, prefer using GetBucketStorageInfo API- CES capacity metrics are suitable for trend analysis and alerting
💡 Best Practice: Batch query bucket capacity via CES capacity metrics
>
When ranking multiple buckets by capacity, calling GetBucketStorageInfo per bucket is slow. Use CES batch query instead:
>
```bash
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=capacity_total \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=average \
--from=<TodayMidnightTimestampMs> \
--to=<CurrentTimestampMs>
```
>
- Use filter=average (not sum), to get the latest sampled value- datapoints[-1].average is the current bucket capacity (Bytes)- CES capacity metrics are collected every 30 minutes, sufficiently accurate for ranking
---
Query Examples
Query bucket extranet download traffic (this month)
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,my-bucket \
--period=86400 \
--filter=sum \
--from=1777564800000 \
--to=1779181505463Query bucket intranet download traffic (this month)
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=download_traffic_intranet \
--dim.0=bucket_name,my-bucket \
--period=86400 \
--filter=sum \
--from=1777564800000 \
--to=1779181505463Query bucket GET request count (this month)
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=get_request_count \
--dim.0=bucket_name,my-bucket \
--period=86400 \
--filter=sum \
--from=1777564800000 \
--to=1779181505463---
References
Related APIs - Huawei Cloud OBS Object Storage Statistics
This document lists all CLI commands and APIs used in the OBS object storage statistics skill.
Table of Contents
- API Overview
- API Details
- 1. ListBucketsWithStats - List Buckets with Capacity and Object Count
- 2. GetTraffic - Query Extranet/Intranet Download Traffic
- 3. GetRequests - Query Total Request Count
- Month-over-Month Calculation
- References
---
API Overview
| Product | CLI Command | API Operation | Description |
|---|---|---|---|
| OBS | hcloud obs ls | obsutil ls | List all buckets (obsutil mode) |
| OBS | hcloud OBS GetBucketStorageInfo | GetBucketStorageInfo | Get bucket storage info (capacity, object count; may not be supported by hcloud) |
| CES | hcloud CES ShowMetricData | ShowMetricData | Query monitoring metric data (traffic, request count, capacity) |
---
API Details
1. ListBucketsWithStats - List Buckets with Capacity and Object Count
⚠️ Key: region parameter must be provided by the user
>
The --region parameter must be explicitly provided by the user. The Agent must not guess or use a default value.>
Pre-check steps:
1. Check whether the user has provided the --region parameter2. If region is missing, immediately ask the user to provide it:
```
Please provide the OBS region, e.g., cn-north-1, cn-north-4, cn-east-2, cn-east-3, cn-south-1, etc.
```
3. If the region is obviously invalid (empty string, pure numbers, special characters), prompt the user
Step 1: List all buckets
⚠️ Key: hcloud OBS module has no ListAllMyBucketsType command
>
hcloud CLI (v7.2.2 tested) does not have the ListAllMyBucketsType command; must use obsutil mode:# List all buckets
hcloud obs ls
# Filter by specific region
hcloud obs ls 2>&1 | grep "cn-south-1"
# Extract bucket names
hcloud obs ls 2>&1 | awk '/obs:\/\// && /cn-south-1/ {print $1}' | sed 's|obs://||'Response key fields:
| Field | Description |
|---|---|
Buckets.Bucket[].Name | Bucket name |
Buckets.Bucket[].Location | Bucket region |
Buckets.Bucket[].CreationDate | Bucket creation time |
Step 2: Get capacity and object count per bucket
⚠️ Key: CES capacity metric batch query recommended for higher efficiency
>
Calling GetBucketStorageInfo per bucket is inefficient; recommended to batch query via CES capacity_total metric:```bash
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=capacity_total \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=average \
--from=<TodayMidnightTimestampMs> \
--to=<CurrentTimestampMs>
```
The returned datapoints[-1].average is the bucket capacity (Bytes).hcloud OBS GetBucketStorageInfo \
--region=<RegionId> \
--bucket=<BucketName>GetBucketStorageInfo response key fields:
| Field | Type | Description |
|---|---|---|
size | long | Total size of objects in the bucket (bytes) |
objectNumber | int | Total number of objects in the bucket |
⚠️ Note: hcloud OBS module may not have GetBucketStorageInfo command
>
If hcloud does not support GetBucketStorageInfo, alternatives:- Query bucket info via obsutil: obsutil ls -bucket=<BucketName> -limit=0 -s- Call OBS API directly: GET /?storageInfo to get bucket storage info>
If obsutil also does not support this query, you can get it by listing all objects in the bucket and summing their sizes (poor performance, use as fallback only).
Error handling: 1. If "Access Denied" is reported, prompt the user to check IAM permissions or bucket policy 2. If bucket count is 0, prompt the user that no buckets exist in the current region; they may need to switch regions 3. If GetBucketStorageInfo errors, skip the bucket and mark "query failed" in the output
---
2. GetTraffic - Query Extranet/Intranet Download Traffic
⚠️ Key: Traffic data is obtained via CES, not directly from OBS API
>
The OBS service itself does not provide traffic statistics APIs; traffic data is collected by CES (Cloud Eye Service).
Required parameters:
| Parameter | hcloud parameter | Description | Example |
|---|---|---|---|
| Region | --region | Bucket region | cn-south-1 |
| Bucket name | --dim.0 | Dimension bucket_name,<BucketName> | bucket_name,my-bucket |
Time range calculation:
⚠️ Key: Time range must precisely match the user's expression
>
| User expression | Time range | Description |
|----------------|-----------|-------------|
| "This month" | 1st of current month 00:00:00 ~ current time | Calendar month |
| "Last 30 days" / "Past month" | Current time - 30 days ~ current time | Rolling 30-day window |
| "Last month" | 1st of previous month 00:00:00 ~ last day of previous month 23:59:59 | Previous calendar month |
| Specific date range | User-specified start and end times | e.g., "May 1 to May 19" |
>
"This month" ≠ "Last 30 days": "This month" starts from the 1st of the current month; "Last 30 days" goes back 30 days from the current time.
Huawei Cloud OBS console defaults to "Last 30 days".
Month-over-month comparison period calculation:
| Query period | Comparison period |
|---|---|
| This month (calendar month) | Previous month (previous calendar month) |
| Last 30 days | 30 days prior (days 31-60) |
| Specific date range | Previous equal-length period |
# This month
Start: 1st of current month 00:00:00 → Unix timestamp (ms)
End: Current time → Unix timestamp (ms)
# Last 30 days
Start: Current time - 30 days → Unix timestamp (ms)
End: Current time → Unix timestamp (ms)
# Previous month (comparison period)
Start: 1st of previous month 00:00:00 → Unix timestamp (ms)
End: Last day of previous month 23:59:59 → Unix timestamp (ms)CLI commands:
⚠️ CES ShowMetricData does not support --User-Agent parameter; do not append it
# Query this month's extranet download traffic
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<FromTimestamp> \
--to=<ToTimestamp>
# Query this month's intranet download traffic
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=download_traffic_intranet \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<FromTimestamp> \
--to=<ToTimestamp>CES ShowMetricData parameter description:
| Parameter | Required | Description |
|---|---|---|
--namespace | Yes | Fixed value SYS.OBS |
--metric_name | Yes | Metric name |
--dim.0 | Yes | Dimension, format bucket_name,<BucketName> |
--period | Yes | Aggregation period, 86400 (1 day) |
--filter | Yes | Aggregation method, sum (sum) |
--from | Yes | Start time (millisecond timestamp) |
--to | Yes | End time (millisecond timestamp) |
Response key fields:
| Field | Description |
|---|---|
datapoints[].average | Average value within the aggregation period |
datapoints[].sum | Sum value within the aggregation period |
datapoints[].timestamp | Data point timestamp |
⚠️ Key: Must use traffic metrics, not bandwidth metrics
>
- ✅ download_traffic_extranet: Extranet download traffic (unit: Bytes, cumulative)- ✅ download_traffic_intranet: Intranet download traffic (unit: Bytes, cumulative)- ❌ download_bytes: Total download bandwidth (unit: Bytes/s, rate, not cumulative)- ❌download_bytes_extranet/download_bytes_intranet: Bandwidth metrics (rate values)
>
Use filter=sum to get total traffic within the time range; summing traffic metrics directly gives total bytes.Results need to be converted to appropriate units:GB = bytes / (1024^3),MB = bytes / (1024^2),KB = bytes / 1024
---
3. GetRequests - Query Total Request Count
⚠️ Key: Request data is obtained via CES, not directly from OBS API
Required parameters: Same as GetTraffic
CLI commands:
⚠️ OBS has no single `request_count` metric; must query each request type separately and sum
# Query GET request count
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=get_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<FromTimestamp> \
--to=<ToTimestamp>
# Query PUT request count
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=put_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<FromTimestamp> \
--to=<ToTimestamp>
# Query POST/DELETE/HEAD request counts (for a complete breakdown)
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=post_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<FromTimestamp> \
--to=<ToTimestamp>Total requests = GET + PUT + POST + DELETE + HEAD (CES has no single request_count metric)⚠️ Note: OBS request billing relevance
>
- GET-type requests (GetObject, HeadObject, ListObjects, etc.)
- PUT-type requests (PutObject, CopyObject, CreateMultipartUpload, etc.)
- Different request types have different billing rates; see OBS pricing page for details
---
Month-over-Month Calculation
Formula:
MoM (%) = (Current Month Value - Last Month Value) / Last Month Value × 100%Special cases:
| Case | Handling |
|---|---|
| Last month value = 0, current month value > 0 | Display "New (last month was 0)" |
| Last month value = 0, current month value = 0 | Display "N/A" |
| Last month value > 0 | Calculate MoM percentage, rounded to 2 decimal places |
Example:
Current month extranet download traffic = 125.3 GB
Last month extranet download traffic = 98.7 GB
MoM = (125.3 - 98.7) / 98.7 × 100% = +26.95%---
References
Task 1: List Buckets with Capacity and Object Counts
⚠️ Important: region must be provided by the user
When querying the bucket list, --region must be explicitly provided by the user. Guessing the region is prohibited.⚠️ Critical: hcloud OBS module does not have a ListAllMyBucketsType command
>
In practice, the hcloud CLI (tested with v7.2.2) OBS module does not include the ListAllMyBucketsType command. You must use obsutil to list buckets:```bash
hcloud obs ls
```
You can filter buckets by region using grep:
```bash
hcloud obs ls 2>&1 | grep "cn-south-1"
```
Step 1: List all buckets (using obsutil)
hcloud obs lsStep 2: Query bucket capacity (CES capacity metric recommended for efficiency)
When batch-querying the capacity of multiple buckets, prefer the CES capacity_total metric to avoid per-bucket API calls:
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=capacity_total \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=average \
--from=<TodayMidnightTimestamp(ms)> \
--to=<CurrentTimestamp(ms)>⚠️ Capacity metric uses `filter=average` (to get the latest sampled value), not filter=sum.The returned datapoints[-1].average is the current bucket capacity (Bytes).Step 2 (Alternative): Query capacity and object count per bucket (via OBS API)
If you need an exact object count, use hcloud OBS GetBucketStorageInfo:
hcloud OBS GetBucketStorageInfo \
--region=<RegionId> \
--bucket=<BucketName>⚠️ Note: GetBucketStorageInfo may not be supported by hcloud
If it returns "No such command", use the alternative: obsutil ls obs://<BucketName> -limit=0 -sKey response fields:
| Field | Description |
|---|---|
size | Total size of objects in the bucket (bytes) |
objectNumber | Total number of objects in the bucket |
Output format example:
Bucket Capacity(GB) Object Count
my-bucket-1 125.3 1024
my-bucket-2 0.5 15
my-bucket-3 2048.0 50000⚠️ Note: GetBucketStorageInfo does not count unrestored archived objects
>
Objects in the Archive storage class must be restored before access; unrestored objects are not counted.
If a bucket contains archived objects, the returned capacity and object count may exclude unrestored archived objects.
💡 Best Practice: Fast Top-N Bucket Capacity Query
>
To find the top N buckets by capacity:
1. hcloud obs ls to list all bucket names in the target region2. Query CES capacity_total metric per bucket to get capacity3. Sort by capacity descending and take the top N
>
This approach is significantly faster than calling GetBucketStorageInfo for each bucket.
Task 3: Query Total Requests (with MoM Comparison)
⚠️ Critical: Request data is obtained via CES (Cloud Eye Service)
>
OBS request monitoring metrics are collected and managed by CES and must be queried through the CES API.
⚠️ Important: Required parameters must be provided by the user
When querying request counts, --region and the bucket name must be explicitly provided by the user. Guessing is prohibited.⚠️ Critical: Time range must precisely match the user's wording (same as Task 2)
>
You must strictly distinguish between "this month" (calendar month) and "last 30 days" (rolling 30-day window), etc.
See the time range reference table in task-query-traffic.md.
Step 1: Determine the time range based on the user's wording (same as Task 2)
Step 2: Query request counts by type
⚠️ CES ShowMetricData does not support the --User-Agent parameter; do not append it
# Query GET request count for the period
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=get_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<StartTimestamp(ms)> \
--to=<EndTimestamp(ms)>
# Query PUT request count
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=put_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<StartTimestamp(ms)> \
--to=<EndTimestamp(ms)>
# Query POST/DELETE/HEAD request counts (for a complete breakdown)
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=post_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<StartTimestamp(ms)> \
--to=<EndTimestamp(ms)>Total requests = GET + PUT + POST + DELETE + HEAD (CES has no single request_count metric)Step 3: Query last period's request counts by type (for MoM calculation)
Replace the time range in Step 2 with the comparison period and query last period's total requests, GET requests, PUT requests, etc.
Step 4: Summary output
OBS Request Report — Bucket: <BucketName>
══════════════════════════════════════════════════════════
Metric Current Period Previous Period MoM Change
───────────────────────────────────────────────────────────────
Total Requests 1,250,000 980,000 +27.55%
GET Requests 1,000,000 800,000 +25.00%
PUT Requests 200,000 160,000 +25.00%
Other Requests 50,000 20,000 +150.00%
══════════════════════════════════════════════════════════
Period: 2026-05-01 ~ 2026-05-19⚠️ Note: MoM special case handling
>
- When previous period value is 0, display MoM as "N/A" (cannot be calculated)
- When previous period value is 0 and current period value > 0, display MoM as "New (previous period was 0)"
- When both current and previous period values are 0, display MoM as "N/A"
CES OBS request metric reference:
| Metric | Description | Unit |
|---|---|---|
get_request_count | GET-type requests | Count |
put_request_count | PUT-type requests | Count |
post_request_count | POST-type requests | Count |
delete_request_count | DELETE-type requests | Count |
head_request_count | HEAD-type requests | Count |
⚠️ Note: OBS has no `request_count` metric
>
There is no OBS metric named request_count in CES. The total request count must be calculated by summing all request types:Total requests = get_request_count + put_request_count + post_request_count + delete_request_count + head_request_countFor detailed metric descriptions, see obs-metrics.md.
Task 2: Query Extranet/Intranet Download Traffic (with MoM Comparison)
⚠️ Critical: Traffic data is obtained via CES (Cloud Eye Service)
>
OBS traffic monitoring metrics are collected and managed by CES (Cloud Eye Service) and must be queried through the CES API.
⚠️ Important: Required parameters must be provided by the user
When querying traffic, --region and the bucket name must be explicitly provided by the user. Guessing is prohibited.⚠️ Critical: Time range must precisely match the user's wording
>
Users may use different time expressions; you must strictly distinguish between them:
>
| User's wording | Time range | Description |
|---------|---------|------|
| "this month" | 1st of current month 00:00:00 ~ now | Calendar month |
| "last 30 days" / "past month" | now - 30 days ~ now | Rolling 30-day window |
| "last month" | 1st of last month 00:00:00 ~ last day of last month 23:59:59 | Previous calendar month |
| Specific date range | User-specified start and end times | e.g., "May 1 to May 19" |
>
⚠️ "This month" and "last 30 days" are different time ranges!
- "This month": starts from the 1st of the current month (e.g., May 1 ~ May 19 = 19 days)
- "Last 30 days": 30 days before now up to now (e.g., April 19 ~ May 19 = 30 days)
- The Huawei Cloud OBS console defaults to a "last 30 days" reporting period; if the user references console data, use the last 30 days
>
Month-over-month comparison period calculation:
- If querying "this month", the comparison period is "last month" (previous calendar month)
- If querying "last 30 days", the comparison period is the 30 days before that (i.e., 30–60 days ago)
- If querying a specific date range, the comparison period is the preceding equal-length window
Step 1: Determine the time range based on the user's wording
Month-over-month formula:
MoM = (Current period value - Comparison period value) / Comparison period value × 100%Step 2: Query extranet download traffic
⚠️ CES ShowMetricData does not support the --User-Agent parameter; do not append it
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<StartTimestamp(ms)> \
--to=<EndTimestamp(ms)>Step 3: Query intranet download traffic
hcloud CES ShowMetricData \
--region=<RegionId> \
--namespace=SYS.OBS \
--metric_name=download_traffic_intranet \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=<StartTimestamp(ms)> \
--to=<EndTimestamp(ms)>Step 4: Query comparison period extranet/intranet download traffic (for MoM calculation)
Replace the time range in Steps 2 and 3 with the comparison period time range and query the extranet and intranet download traffic for that period.
Step 5: Summary output
OBS Download Traffic Report — Bucket: <BucketName>
══════════════════════════════════════════════════════════
Metric Current Period Previous Period MoM Change
───────────────────────────────────────────────────────────────
Extranet Download 125.3 GB 98.7 GB +26.95%
Intranet Download 50.2 GB 45.0 GB +11.56%
Total Download 175.5 GB 143.7 GB +22.13%
══════════════════════════════════════════════════════════
Period: 2026-05-01 ~ 2026-05-19⚠️ CES ShowMetricData parameter reference
>
- --namespace=SYS.OBS: The CES namespace for OBS---dim.0=bucket_name,<BucketName>: Dimension format iskey,value; the OBS dimension key isbucket_name
- --period=86400: Aggregation period of 86400 seconds (1 day), used for daily aggregation and summation- --filter=sum: Aggregation method is summation---from/--to: Timestamps in millisecond-level Unix time
⚠️ Critical: You must use traffic metrics, not bandwidth metrics
>
- ✅ download_traffic_extranet: Extranet download traffic (unit: Bytes, cumulative)- ✅ download_traffic_intranet: Intranet download traffic (unit: Bytes, cumulative)- ❌ download_bytes: Total download bandwidth (unit: Bytes/s, rate value — not cumulative)- ❌download_bytes_extranet/download_bytes_intranet: Bandwidth metrics (rate values)
>
Traffic metrics can be summed directly to get total traffic; bandwidth metrics must be multiplied by the aggregation period to convert, which is error-prone. Always use traffic metrics.
CES OBS traffic metric reference:
| Metric | Description | Unit |
|---|---|---|
download_traffic_extranet | Extranet download traffic | Bytes |
download_traffic_intranet | Intranet download traffic | Bytes |
For detailed metric descriptions, see obs-metrics.md.
Troubleshooting - Huawei Cloud OBS Object Storage Statistics
Table of Contents
- hcloud CLI Issues
- CES Monitoring Data Issues
- Bucket Capacity Query Issues
- Month-over-Month Calculation Issues
---
hcloud CLI Issues
1. hcloud OBS module has no ListAllMyBucketsType command
Problem: Running hcloud OBS ListAllMyBucketsType returns Error: No such command: "ListAllMyBucketsType".
Root cause: hcloud CLI (v7.2.2 tested) OBS module does not include the ListAllMyBucketsType command. The hcloud OBS module only provides a limited set of bucket management operations; listing buckets requires the obsutil mode.
Solution:
# List all buckets
hcloud obs ls
# Filter buckets in a specific region
hcloud obs ls 2>&1 | grep "cn-south-1"
# Extract bucket name list
hcloud obs ls 2>&1 | awk '/obs:\/\// && /cn-south-1/ {print $1}' | sed 's|obs://||'2. hcloud OBS module has no GetBucketStorageInfo command
Problem: Running hcloud OBS GetBucketStorageInfo returns command not found.
Root cause: The hcloud CLI OBS module may not include all OBS API operations; GetBucketStorageInfo is a bucket extension API not supported by some hcloud versions.
Solution:
Method 1: Use CES capacity metric (recommended for batch queries)
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=capacity_total \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=average \
--from=<TodayMidnightTimestampMs> \
--to=<CurrentTimestampMs>The returned datapoints[-1].average is the bucket capacity (Bytes).
Method 2: Use obsutil as alternative
# Use obsutil to list objects and get statistics
obsutil ls obs://<BucketName> -limit=0 -sMethod 3: Use OBS REST API directly
# Call OBS REST API via curl to get bucket storage info
# GET /?storageInfo
curl -X GET "https://<BucketName>.obs.<RegionId>.myhuaweicloud.com/?storageInfo" \
-H "Date: $(date -u '+%a, %d %b %Y %H:%M:%S GMT')" \
-H "Authorization: OBS <Signature>"Method 4: Use OBS SDK
from obs import ObsClient
obs_client = ObsClient(...)
resp = obs_client.getBucketStorageInfo(bucketName)
print(f"Size: {resp.body.size}, Objects: {resp.body.objectNumber}")3. hcloud CES ShowMetricData parameter format issue
Problem: CES ShowMetricData dimensions parameter format is incorrect.
Correct format:
--dim.0=bucket_name,my-bucketCommon errors:
# ❌ Incorrect: SDK format, not supported by hcloud
--dimensions.0.name=bucket_name --dimensions.0.value=my-bucket
# ❌ Incorrect: dimensions index starts from 1
--dim.1=bucket_name,my-bucket
# ❌ Incorrect: dimension key is wrong
--dim.0=bucket,my-buckethcloud CES uses `--dim.N=key,value` format, with index starting from 0.
4. hcloud credential configuration issues
| Error message | Cause | Solution |
|---|---|---|
No valid credential | AK/SK not configured | Run hcloud configure |
Access denied | AK/SK invalid or expired | Reconfigure credentials |
Invalid region | Region ID incorrect | Use the correct region ID |
Please set ak, sk and endpoint | obsutil credentials not configured | Run hcloud obs config -i=<AK> -k=<SK> -e=obs.<region>.myhuaweicloud.com |
InvalidAccessKeyId | obsutil configured AK/SK is invalid | Re-run hcloud obs config with correct credentials |
⚠️ obsutil credential check process
>
Before any OBS operation, verify that obsutil credentials are available:
```bash
hcloud obs ls -limit=1
```
If the response isPlease set ak, sk and endpoint in the configuration file!orInvalidAccessKeyId,
inform the user of the following example command and have them configure it in their terminal:
>
```
obsutil credentials are not configured. Please run the following command in your terminal to configure (AK/SK can be obtained from the Huawei Cloud console "My Credentials" page):
>
hcloud obs config -i=<YourAK> -k=<YourSK> -e=obs.<Region>.myhuaweicloud.com
>
Example (Guangzhou region):
hcloud obs config -i=<YourAK> -k=<YourSK> -e=obs.cn-south-1.myhuaweicloud.com
>
Common Endpoints:
cn-north-4 → obs.cn-north-4.myhuaweicloud.com
cn-east-3 → obs.cn-east-3.myhuaweicloud.com
cn-south-1 → obs.cn-south-1.myhuaweicloud.com
cn-southwest-2 → obs.cn-southwest-2.myhuaweicloud.com
>
Retry after configuration is complete.
```
---
CES Monitoring Data Issues
1. CES query returns empty data
Problem: CES ShowMetricData returns an empty datapoints array.
Possible causes and solutions:
1. Incorrect bucket name
- Confirm dim.0 uses the correct bucket name
2. No data in time range
- Bucket has no corresponding operations in the time period (e.g., no download traffic, no requests)
- Try expanding the time range to verify
3. CES data collection delay
- CES metric data typically has a 1-5 minute delay
- If querying data from the last few minutes, it may not have been collected yet
4. Incorrect namespace or metric name
- Confirm namespace is
SYS.OBS(notOBSorSYS.OBJECT_STORAGE) - Confirm metric_name is correct (e.g.,
download_traffic_extranetnotdownload_flow)
5. period parameter mismatch
- Data granularity must match period
- OBS monitoring metrics default collection period is 5 minutes
- For long-term queries, set period to 86400 (1 day)
2. CES ShowMetricData parameter format errors
Key parameter reference:
| Parameter | Correct Value | Common Error |
|---|---|---|
--namespace | SYS.OBS | OBS, SYS.OBJECT_STORAGE |
--metric_name | download_traffic_extranet | downloadBytes, download_flow |
--dim.0 | bucket_name,my-bucket | bucket,my-bucket, bucketName,my-bucket |
--period | 86400 | 86400000 (milliseconds instead of seconds) |
--filter | sum | SUM, total |
--from/--to | Millisecond timestamp (13 digits) | Second timestamp (10 digits) |
3. CES ShowMetricData does not support --User-Agent parameter
Problem: Running hcloud CES ShowMetricData --User-Agent=xxx returns error [USE_ERROR]Invalid parameter:User-Agent.
Root cause: The CES module's ShowMetricData command does not support the --User-Agent parameter. This parameter is only available in some OBS module commands.
Solution: CES query commands must not append the --User-Agent parameter.
4. Month-over-month with last month data being 0
Problem: Last month traffic or request data is 0, making MoM calculation impossible.
Possible causes:
- Bucket was just created last month with no operation data
- CES monitoring was not enabled or data collection did not cover last month
- Time range calculation error
Handling:
- Last month=0 and current month>0: Display "New (last month was 0)"
- Last month=0 and current month=0: Display "N/A"
---
Bucket Capacity Query Issues
1. Archived bucket capacity display is incomplete
Problem: GetBucketStorageInfo returns capacity and object count less than actual values.
Root cause: Archived storage class objects need to be restored before they can be accessed; unrestored objects are not counted.
Solution:
- Archived objects must be restored (RestoreObject) before they can be counted
- For accurate archived object statistics, use CES monitoring metrics
cold_storage_bytes/cold_object_count
2. GetBucketStorageInfo performance issues
Problem: Querying capacity for buckets with large numbers of objects (millions+) takes a long time.
Solution:
- Use CES monitoring metrics
standard_storage_bytes/standard_object_countas an alternative (slightly less real-time but better performance) - Set query timeout and retry
---
Month-over-Month Calculation Issues
1. Time range calculation errors
Correct calculation method:
# Current month start time
current_month_start = "$(date +%Y-%m-01)" # e.g., 2026-05-01
# Convert to millisecond timestamp
from_timestamp = $(date -d "$current_month_start" +%s)000 # e.g., 1746057600000
# Current month end time (current time)
to_timestamp = $(date +%s)000
# Last month start time
last_month_start = "$(date -d "$(date +%Y-%m-01) -1 month" +%Y-%m-01)"
# Last month end time (last day of previous month 23:59:59)
last_month_end = "$(date -d "$(date +%Y-%m-01) -1 second" +%Y-%m-%dT23:59:59)"2. Traffic unit conversion
Bytes → KB: / 1024
Bytes → MB: / (1024 * 1024)
Bytes → GB: / (1024 * 1024 * 1024)
Bytes → TB: / (1024 * 1024 * 1024 * 1024)Recommendation: Choose an appropriate display unit based on traffic size:
- < 1 MB → Display KB
- < 1 GB → Display MB
- < 1 TB → Display GB
- >= 1 TB → Display TB
---
References
Verification Method - Huawei Cloud OBS Object Storage Statistics
Table of Contents
---
Verify Bucket List Query
Step 1: List buckets
hcloud obs lsExpected result:
- Returns a bucket list, each bucket containing
Name,Location,CreationDate - If no buckets exist, returns an empty list (normal)
Step 2: Query bucket capacity and object count
hcloud OBS GetBucketStorageInfo \
--region=cn-south-1 \
--bucket=<BucketName>Expected result:
- Returns
size(bytes) andobjectNumber(object count) - size >= 0, objectNumber >= 0
Step 3: Verify output format
Bucket Capacity(GB) Objects
my-bucket-1 125.3 1024
my-bucket-2 0.5 15Verification items:
- ✅ Capacity is in GB, with 1 decimal place
- ✅ Object count is an integer
- ✅ All buckets have been queried
---
Verify Traffic Query
Step 1: Calculate time range
# Current month start timestamp (ms)
FROM_TS=$(($(date -d "$(date +%Y-%m-01)" +%s) * 1000))
# Current timestamp (ms)
TO_TS=$(($(date +%s) * 1000))
# Last month start timestamp (ms)
LAST_MONTH_FROM_TS=$(($(date -d "$(date -d "$(date +%Y-%m-01) -1 month" +%Y-%m-01)" +%s) * 1000))
# Last month end timestamp (ms)
LAST_MONTH_TO_TS=$(($(date -d "$(date +%Y-%m-01) -1 second" +%s) * 1000))Step 2: Query current month extranet download traffic
⚠️ CES ShowMetricData does not support --User-Agent parameter; do not append it
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=$FROM_TS \
--to=$TO_TSExpected result:
- Returns datapoints array
- Each datapoint contains timestamp and sum value
Step 3: Query last month extranet download traffic
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=$LAST_MONTH_FROM_TS \
--to=$LAST_MONTH_TO_TSStep 4: Verify month-over-month calculation
MoM (%) = (Current Month Value - Last Month Value) / Last Month Value × 100%Verification items:
- ✅ Traffic value returned in Bytes, needs to be converted to GB for display
- ✅ MoM percentage rounded to 2 decimal places
- ✅ Special handling when last month value is 0
---
Verify Request Query
Step 1: Query current month GET request count
⚠️ OBS has no single `request_count` metric; must query each type separately
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=get_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=$FROM_TS \
--to=$TO_TSExpected result:
- Returns datapoints array, sum value is the request count
Step 2: Query request count by type
# GET request count
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=get_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=$FROM_TS \
--to=$TO_TS
# PUT request count
hcloud CES ShowMetricData \
--region=cn-south-1 \
--namespace=SYS.OBS \
--metric_name=put_request_count \
--dim.0=bucket_name,<BucketName> \
--period=86400 \
--filter=sum \
--from=$FROM_TS \
--to=$TO_TSStep 3: Verify aggregation
Verification items:
- ✅ Total requests = sum of all individual request types (GET + PUT + POST + DELETE + HEAD)
- ✅ All request counts >= 0
- ✅ MoM calculation is correct
---
End-to-End Verification Script
#!/bin/bash
# OBS statistics skill end-to-end verification script
REGION="${1:-cn-south-1}"
BUCKET_NAME="${2}"
if [ -z "$BUCKET_NAME" ]; then
echo "Usage: $0 <region> <bucket_name>"
exit 1
fi
echo "=========================================="
echo "OBS Statistics Skill End-to-End Verification"
echo "Region: $REGION"
echo "Bucket: $BUCKET_NAME"
echo "=========================================="
# 1. Verify hcloud
echo -e "\n[1/6] Verifying hcloud version..."
hcloud version
# 2. Verify obsutil
echo -e "\n[2/6] Verifying obsutil version..."
obsutil version
# 3. Verify bucket list
echo -e "\n[3/6] Verifying bucket list query..."
hcloud obs ls
# 4. Verify bucket capacity
echo -e "\n[4/6] Verifying bucket capacity query..."
hcloud OBS GetBucketStorageInfo \
--region=$REGION \
--bucket=$BUCKET_NAME
# 5. Verify CES traffic metrics
FROM_TS=$(($(date -d "$(date +%Y-%m-01)" +%s) * 1000))
TO_TS=$(($(date +%s) * 1000))
echo -e "\n[5/6] Verifying CES extranet download traffic query..."
hcloud CES ShowMetricData \
--region=$REGION \
--namespace=SYS.OBS \
--metric_name=download_traffic_extranet \
--dim.0=bucket_name,$BUCKET_NAME \
--period=86400 \
--filter=sum \
--from=$FROM_TS \
--to=$TO_TS
# 6. Verify CES request metrics
echo -e "\n[6/6] Verifying CES GET request count query..."
hcloud CES ShowMetricData \
--region=$REGION \
--namespace=SYS.OBS \
--metric_name=get_request_count \
--dim.0=bucket_name,$BUCKET_NAME \
--period=86400 \
--filter=sum \
--from=$FROM_TS \
--to=$TO_TS
echo -e "\n=========================================="
echo "Verification complete!"
echo "=========================================="---
Error Handling
| Error Code | Description | Troubleshooting Command |
|---|---|---|
| 403 | Insufficient permissions | hcloud configure list to check credentials |
| 404 | Bucket does not exist | obsutil ls -limit=100 to list buckets |
| 400 | Invalid request parameters | Check region, bucket name, and other parameters |
| 500 | Internal service error | Retry later or contact Huawei Cloud technical support |
| Empty datapoints | No CES data | Check namespace, metric_name, and time range |
#!/usr/bin/env python3
"""
OBS Bucket Total Request Statistics Script
Queries OBS bucket request counts by type via Huawei Cloud CES (Cloud Eye Service),
sums the total requests, and calculates the month-over-month change.
Usage:
python3 obs_request_stats.py --region cn-south-1 --bucket obs-60030508 --period last_30d
python3 obs_request_stats.py --region cn-south-1 --bucket obs-60030508 --period this_month
python3 obs_request_stats.py --region cn-south-1 --bucket obs-60030508 --from 2026-04-20 --to 2026-05-20
Key lessons learned:
1. OBS has no single request_count metric; you must query get/put/post/delete/head_request_count separately and sum them
2. hcloud CES dimension parameter format: --dim.0=bucket_name,<BucketName>, not the SDK dimensions format
3. Time ranges: "this month" = calendar month (1st of month ~ now), "last 30 days" = rolling 30-day window (now - 30 days ~ now)
4. The sum values returned by CES can be directly accumulated for total request count; no conversion needed
5. All hcloud parameters must use the --param=value format (connected with equals sign)
"""
import argparse
import json
import subprocess
import sys
from datetime import datetime, timedelta
from typing import Optional
OBS_NAMESPACE = "SYS.OBS"
DAILY_PERIOD = 86400
REQUEST_METRICS = {
"GET": "get_request_count",
"PUT": "put_request_count",
"POST": "post_request_count",
"DELETE": "delete_request_count",
"HEAD": "head_request_count",
}
ERROR_METRICS = {
"4xx": "request_count_4xx",
"5xx": "request_count_5xx",
}
def dt_to_ms(dt: datetime) -> int:
return int(dt.timestamp() * 1000)
def fmt_count(n: int) -> str:
if n >= 1_000_000:
return f"{n / 1_000_000:.2f} M"
if n >= 1_000:
return f"{n / 1_000:.2f} K"
return str(n)
def calc_pct(current: float, previous: float) -> str:
if previous == 0:
return "N/A" if current == 0 else "New (previous period was 0)"
return f"{(current - previous) / previous * 100:+.2f}%"
def resolve_time_range(period: str, from_str: Optional[str], to_str: Optional[str]):
now = datetime.now()
if from_str and to_str:
from_dt = datetime.strptime(from_str, "%Y-%m-%d")
to_dt = datetime.strptime(to_str, "%Y-%m-%d") + timedelta(days=1) - timedelta(seconds=1)
elif period == "this_month":
from_dt = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
to_dt = now
elif period == "last_month":
first_of_this_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
to_dt = first_of_this_month - timedelta(seconds=1)
from_dt = to_dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
elif period == "last_30d":
from_dt = now - timedelta(days=30)
to_dt = now
else:
raise ValueError(f"Unsupported period: {period}. Options: this_month, last_month, last_30d")
duration = to_dt - from_dt
compare_to = from_dt
compare_from = from_dt - duration
return from_dt, to_dt, compare_from, compare_to
def query_ces_metric(region: str, metric_name: str, bucket: str, from_ms: int, to_ms: int) -> dict:
cmd = [
"hcloud", "CES", "ShowMetricData",
f"--region={region}",
f"--namespace={OBS_NAMESPACE}",
f"--metric_name={metric_name}",
f"--dim.0=bucket_name,{bucket}",
f"--period={DAILY_PERIOD}",
"--filter=sum",
f"--from={from_ms}",
f"--to={to_ms}",
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Warning: Query for {metric_name} failed: {result.stderr.strip()}", file=sys.stderr)
return {"datapoints": [], "metric_name": metric_name}
return json.loads(result.stdout)
def sum_metric(resp: dict) -> int:
total = 0
for dp in resp.get("datapoints", []):
total += dp.get("sum", 0)
return int(total)
def query_requests(region: str, bucket: str, from_ms: int, to_ms: int,
include_errors: bool = False) -> dict:
result = {}
total = 0
for label, metric_name in REQUEST_METRICS.items():
resp = query_ces_metric(region, metric_name, bucket, from_ms, to_ms)
val = sum_metric(resp)
result[label] = val
total += val
result["total"] = total
if include_errors:
for label, metric_name in ERROR_METRICS.items():
resp = query_ces_metric(region, metric_name, bucket, from_ms, to_ms)
result[label] = sum_metric(resp)
return result
def print_request_report(bucket: str, cur: dict, cmp: dict,
from_dt: datetime, to_dt: datetime,
compare_from: datetime, compare_to: datetime,
include_errors: bool = False):
rows = [("Total Requests", "total")] + [(f"{k} Requests", k) for k in REQUEST_METRICS.keys()]
if include_errors:
rows += [(f"{k} Status Codes", k) for k in ERROR_METRICS.keys()]
print(f"OBS Request Report — Bucket: {bucket}")
print("═" * 64)
print(f"{'Metric':<14s}{'Current Period':<20s}{'Comparison Period':<20s}{'MoM Change'}")
print("─" * 64)
for label, key in rows:
cur_val = cur[key]
cmp_val = cmp[key]
print(f"{label:<14s}{fmt_count(cur_val):<20s}{fmt_count(cmp_val):<20s}{calc_pct(cur_val, cmp_val)}")
print("═" * 64)
print(f"Current Period: {from_dt.strftime('%Y-%m-%d')} ~ {to_dt.strftime('%Y-%m-%d')}")
print(f"Comparison Period: {compare_from.strftime('%Y-%m-%d')} ~ {compare_to.strftime('%Y-%m-%d')}")
def main():
parser = argparse.ArgumentParser(description="OBS Bucket Total Request Statistics")
parser.add_argument("--region", required=True, help="Huawei Cloud region, e.g., cn-south-1")
parser.add_argument("--bucket", required=True, help="OBS bucket name")
parser.add_argument("--period", choices=["this_month", "last_month", "last_30d"],
help="Time period: this_month (this month), last_month (last month), last_30d (last 30 days)")
parser.add_argument("--from", dest="from_str", help="Custom start date, format: YYYY-MM-DD")
parser.add_argument("--to", dest="to_str", help="Custom end date, format: YYYY-MM-DD")
parser.add_argument("--include-errors", action="store_true",
help="Also query 4xx/5xx error request counts")
args = parser.parse_args()
if not args.period and not (args.from_str and args.to_str):
parser.error("Either --period or --from/--to must be specified")
from_dt, to_dt, compare_from, compare_to = resolve_time_range(
args.period, args.from_str, args.to_str
)
from_ms = dt_to_ms(from_dt)
to_ms = dt_to_ms(to_dt)
compare_from_ms = dt_to_ms(compare_from)
compare_to_ms = dt_to_ms(compare_to)
cur = query_requests(args.region, args.bucket, from_ms, to_ms,
include_errors=args.include_errors)
cmp = query_requests(args.region, args.bucket, compare_from_ms, compare_to_ms,
include_errors=args.include_errors)
print()
print_request_report(args.bucket, cur, cmp, from_dt, to_dt,
compare_from, compare_to,
include_errors=args.include_errors)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
OBS Bucket Download Traffic Statistics Script
Queries OBS bucket extranet/intranet download traffic via Huawei Cloud CES (Cloud Eye Service)
and calculates the month-over-month change.
Usage:
python3 obs_traffic_stats.py --region cn-south-1 --bucket obs-60030508 --period last_month
python3 obs_traffic_stats.py --region cn-south-1 --bucket obs-60030508 --period this_month
python3 obs_traffic_stats.py --region cn-south-1 --bucket obs-60030508 --from 2026-04-20 --to 2026-05-20
Key lessons learned:
1. You must use traffic metrics (download_traffic_extranet/download_traffic_intranet), not bandwidth metrics (download_bytes)
2. hcloud CES dimension parameter format: --dim.0=bucket_name,<BucketName>, not the SDK dimensions format
3. Time ranges: "this month" = calendar month (1st of month ~ now), "last 30 days" = rolling 30-day window (now - 30 days ~ now)
4. The sum values returned by CES can be directly accumulated for total bytes; no need to multiply by the aggregation period
5. All hcloud parameters must use the --param=value format (connected with equals sign)
"""
import argparse
import json
import subprocess
import sys
from datetime import datetime, timedelta
from typing import Optional
OBS_NAMESPACE = "SYS.OBS"
DAILY_PERIOD = 86400
TRAFFIC_METRICS = {
"extranet": "download_traffic_extranet",
"intranet": "download_traffic_intranet",
}
UPLOAD_TRAFFIC_METRICS = {
"extranet": "upload_traffic_extranet",
"intranet": "upload_traffic_intranet",
}
REQUEST_METRICS = [
"get_request_count",
"put_request_count",
"post_request_count",
"delete_request_count",
"head_request_count",
]
def dt_to_ms(dt: datetime) -> int:
return int(dt.timestamp() * 1000)
def ms_to_dt(ms: int) -> datetime:
return datetime.fromtimestamp(ms / 1000)
def fmt_bytes(b: float) -> str:
if b >= 1024 ** 4:
return f"{b / (1024 ** 4):.2f} TB"
if b >= 1024 ** 3:
return f"{b / (1024 ** 3):.2f} GB"
if b >= 1024 ** 2:
return f"{b / (1024 ** 2):.2f} MB"
if b >= 1024:
return f"{b / 1024:.2f} KB"
return f"{b:.2f} Bytes"
def calc_pct(current: float, previous: float) -> str:
if previous == 0:
return "N/A" if current == 0 else "New (previous period was 0)"
return f"{(current - previous) / previous * 100:+.2f}%"
def resolve_time_range(period: str, from_str: Optional[str], to_str: Optional[str]):
now = datetime.now()
if from_str and to_str:
from_dt = datetime.strptime(from_str, "%Y-%m-%d")
to_dt = datetime.strptime(to_str, "%Y-%m-%d") + timedelta(days=1) - timedelta(seconds=1)
elif period == "this_month":
from_dt = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
to_dt = now
elif period == "last_month":
first_of_this_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
to_dt = first_of_this_month - timedelta(seconds=1)
from_dt = to_dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
elif period == "last_30d":
from_dt = now - timedelta(days=30)
to_dt = now
else:
raise ValueError(f"Unsupported period: {period}. Options: this_month, last_month, last_30d")
duration = to_dt - from_dt
compare_to = from_dt
compare_from = from_dt - duration
return from_dt, to_dt, compare_from, compare_to
def query_ces_metric(region: str, metric_name: str, bucket: str, from_ms: int, to_ms: int) -> dict:
cmd = [
"hcloud", "CES", "ShowMetricData",
f"--region={region}",
f"--namespace={OBS_NAMESPACE}",
f"--metric_name={metric_name}",
f"--dim.0=bucket_name,{bucket}",
f"--period={DAILY_PERIOD}",
"--filter=sum",
f"--from={from_ms}",
f"--to={to_ms}",
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Warning: Query for {metric_name} failed: {result.stderr.strip()}", file=sys.stderr)
return {"datapoints": [], "metric_name": metric_name}
return json.loads(result.stdout)
def sum_traffic(resp: dict) -> int:
total = 0
for dp in resp.get("datapoints", []):
total += dp.get("sum", 0)
return total
def query_traffic(region: str, bucket: str, from_ms: int, to_ms: int, direction: str = "download") -> dict:
metrics = TRAFFIC_METRICS if direction == "download" else UPLOAD_TRAFFIC_METRICS
result = {}
for key, metric_name in metrics.items():
resp = query_ces_metric(region, metric_name, bucket, from_ms, to_ms)
result[key] = sum_traffic(resp)
result["total"] = result["extranet"] + result["intranet"]
return result
def print_traffic_report(bucket: str, cur: dict, cmp: dict, from_dt: datetime, to_dt: datetime,
compare_from: datetime, compare_to: datetime, direction: str = "Download"):
label_map = {"extranet": "Extranet ", "intranet": "Intranet ", "total": "Total "}
print(f"OBS {direction} Traffic Report — Bucket: {bucket}")
print("═" * 60)
print(f"{'Metric':<12s}{'Current Period':<20s}{'Comparison Period':<20s}{'MoM Change'}")
print("─" * 60)
for key in ["extranet", "intranet", "total"]:
label = f"{label_map[key]}{direction}"
cur_val = cur[key]
cmp_val = cmp[key]
print(f"{label:<12s}{fmt_bytes(cur_val):<20s}{fmt_bytes(cmp_val):<20s}{calc_pct(cur_val, cmp_val)}")
print("═" * 60)
print(f"Current Period: {from_dt.strftime('%Y-%m-%d')} ~ {to_dt.strftime('%Y-%m-%d')}")
print(f"Comparison Period: {compare_from.strftime('%Y-%m-%d')} ~ {compare_to.strftime('%Y-%m-%d')}")
def main():
parser = argparse.ArgumentParser(description="OBS Bucket Download Traffic Statistics")
parser.add_argument("--region", required=True, help="Huawei Cloud region, e.g., cn-south-1")
parser.add_argument("--bucket", required=True, help="OBS bucket name")
parser.add_argument("--period", choices=["this_month", "last_month", "last_30d"],
help="Time period: this_month (this month), last_month (last month), last_30d (last 30 days)")
parser.add_argument("--from", dest="from_str", help="Custom start date, format: YYYY-MM-DD")
parser.add_argument("--to", dest="to_str", help="Custom end date, format: YYYY-MM-DD")
parser.add_argument("--direction", choices=["download", "upload", "both"], default="download",
help="Traffic direction: download, upload, both (download + upload)")
args = parser.parse_args()
if not args.period and not (args.from_str and args.to_str):
parser.error("Either --period or --from/--to must be specified")
from_dt, to_dt, compare_from, compare_to = resolve_time_range(
args.period, args.from_str, args.to_str
)
from_ms = dt_to_ms(from_dt)
to_ms = dt_to_ms(to_dt)
compare_from_ms = dt_to_ms(compare_from)
compare_to_ms = dt_to_ms(compare_to)
directions = []
if args.direction in ("download", "both"):
directions.append("download")
if args.direction in ("upload", "both"):
directions.append("upload")
for d in directions:
label = "Download" if d == "download" else "Upload"
cur = query_traffic(args.region, args.bucket, from_ms, to_ms, direction=d)
cmp = query_traffic(args.region, args.bucket, compare_from_ms, compare_to_ms, direction=d)
print()
print_traffic_report(args.bucket, cur, cmp, from_dt, to_dt, compare_from, compare_to, direction=label)
if __name__ == "__main__":
main()