You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.Net MVC中能否通过单次Elasticsearch API调用获取指定多类监控指标?

Elasticsearch Metrics in ASP.NET MVC: Answers & Updated Code

Great question! Let's break down your two questions and update your method to fetch all the metrics you need.

问题1:能否通过一次Elasticsearch API调用获取所有上述指标?

No — these metrics are spread across multiple Elasticsearch API endpoints because they track different parts of the cluster (cluster health, node-specific details, index stats, and task status). Here's how each metric maps to an API:

  • Version, Up-time, Disk Available in %, JVM Heap Size: GET /_nodes/_local (returns details for the local node, including version, uptime, disk usage, and JVM memory stats)
  • Overall Health, No. of Nodes, Primary Shards, Replica Shards: GET /_cluster/health (core cluster health metrics)
  • No. of Indices: GET /_cat/indices?format=json (returns a list of all indices; we count the entries)
  • No. of Jobs: Assuming you mean pending cluster tasks (like shard allocations), use GET /_cluster/pending_tasks (counts unprocessed cluster tasks). If you're referring to scheduled jobs (like ILM policies), you'd use a different endpoint like GET /_ilm/policy.

问题2:如何通过单次API调用结合不同指标检查Elasticsearch健康状态?

While you can't get all your desired metrics in one call, you can use GET /_cluster/health as a single source for critical health checks. It covers the most impactful signals to assess cluster health:

  • Overall Health: The status field (green = all shards active, yellow = all primaries active but some replicas unassigned, red = some primaries unassigned)
  • Node Count: number_of_nodes (verify this matches your expected cluster size)
  • Shard Health: active_primary_shards (all primaries should be active) and active_replica_shards (ensure replicas are assigned correctly)

For a full health check that includes disk, JVM, and version, you'll need to combine calls to multiple APIs — but you can wrap all these calls into a single method in your ASP.NET MVC app, as shown below.

Updated Method to Fetch All Required Metrics

Here's a revised version of your method that gathers all your requested metrics by calling the necessary APIs, with best practices like async/await to avoid blocking threads:

using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;

private static async Task<string> GetElasticsearchFullMetrics()
{
    var esBaseUrl = "http://localhost:9200";
    using var httpClient = new HttpClient();
    try
    {
        // 1. Fetch cluster health metrics
        var healthResponse = await httpClient.GetAsync($"{esBaseUrl}/_cluster/health");
        if (!healthResponse.IsSuccessStatusCode)
        {
            return $"Error fetching cluster health: {healthResponse.StatusCode}";
        }
        var healthData = JObject.Parse(await healthResponse.Content.ReadAsStringAsync());

        // 2. Fetch local node details (version, uptime, disk, JVM)
        var nodeResponse = await httpClient.GetAsync($"{esBaseUrl}/_nodes/_local");
        if (!nodeResponse.IsSuccessStatusCode)
        {
            return $"Error fetching node details: {nodeResponse.StatusCode}";
        }
        var nodeData = JObject.Parse(await nodeResponse.Content.ReadAsStringAsync());
        var localNode = nodeData["nodes"].First.First; // Extract the local node's data

        // 3. Fetch index count
        var indicesResponse = await httpClient.GetAsync($"{esBaseUrl}/_cat/indices?format=json");
        if (!indicesResponse.IsSuccessStatusCode)
        {
            return $"Error fetching indices: {indicesResponse.StatusCode}";
        }
        var indicesData = JArray.Parse(await indicesResponse.Content.ReadAsStringAsync());
        int totalIndices = indicesData.Count;

        // 4. Fetch pending tasks (for "No. of Jobs")
        var tasksResponse = await httpClient.GetAsync($"{esBaseUrl}/_cluster/pending_tasks");
        if (!tasksResponse.IsSuccessStatusCode)
        {
            return $"Error fetching pending tasks: {tasksResponse.StatusCode}";
        }
        var tasksData = JObject.Parse(await tasksResponse.Content.ReadAsStringAsync());
        int pendingJobs = tasksData["tasks"].Count();

        // Calculate disk available percentage
        long totalDiskBytes = localNode["fs"]["total"]["total_in_bytes"].Value<long>();
        long availableDiskBytes = localNode["fs"]["total"]["available_in_bytes"].Value<long>();
        double diskAvailablePercent = Math.Round((double)availableDiskBytes / totalDiskBytes * 100, 2);

        // Format metrics into a readable string (or return a strongly-typed DTO for your app)
        var metricsSummary = $"Elasticsearch Cluster Metrics:\n" +
                              $"• Version: {localNode["version"]}\n" +
                              $"• Up-time: {TimeSpan.FromMilliseconds(localNode["jvm"]["uptime_in_millis"].Value<long>())}\n" +
                              $"• No. of Jobs (Pending Tasks): {pendingJobs}\n" +
                              $"• Overall Health: {healthData["status"].ToString().ToUpper()}\n" +
                              $"• No. of Nodes: {healthData["number_of_nodes"]}\n" +
                              $"• Disk Available: {diskAvailablePercent}%\n" +
                              $"• JVM Heap Max: {FormatBytes(localNode["jvm"]["mem"]["heap_max_in_bytes"].Value<long>())}\n" +
                              $"• JVM Heap Used: {FormatBytes(localNode["jvm"]["mem"]["heap_used_in_bytes"].Value<long>())}\n" +
                              $"• No. of Indices: {totalIndices}\n" +
                              $"• Primary Shards: {healthData["active_primary_shards"]}\n" +
                              $"• Replica Shards: {healthData["active_replica_shards"]}";

        return metricsSummary;
    }
    catch (Exception ex)
    {
        return $"Error retrieving Elasticsearch metrics: {ex.Message}";
    }
}

// Helper method to convert bytes to human-readable format
private static string FormatBytes(long bytes)
{
    string[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB" };
    int counter = 0;
    double size = bytes;
    while (size >= 1024 && counter < sizeSuffixes.Length - 1)
    {
        size /= 1024;
        counter++;
    }
    return $"{size:N2} {sizeSuffixes[counter]}";
}

Key Improvements:

  • Uses async/await instead of .Result to prevent thread blocking (critical for ASP.NET MVC performance)
  • Aggregates data from 4 APIs to collect all your requested metrics
  • Includes a helper method to make JVM heap sizes and disk space easier to read
  • Handles errors for each API call individually for better debugging

内容的提问来源于stack exchange,提问作者Harish Shisode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 07:49:05