用fastjson解析streamsets接口返回的复杂json

Streamsets提供了丰富的restful接口,通过swagger方式提供,使用很方便,功能很强大。

地址: http://localhost:18630/collector/restapi

这里我们在对Streamsets做二次开发的时候,需要解析返回结果并保存到数据库中,这里把几个有代表性的json解析方式讲解一下。

1、查询所有任务的运行状态

在manager分组下, 不需要参数,直接通过GET  /rest/v1/pipelines/status

返回结果如下:

{
  "addNewPipeline": {
    "pipelineId": "addNewPipeline",
    "rev": "0",
    "user": "admin",
    "status": "EDITED",
    "message": "Pipeline edited",
    "timeStamp": 1556437391339,
    "attributes": {
      "IS_REMOTE_PIPELINE": false
    },
    "executionMode": "STANDALONE",
    "metrics": null,
    "retryAttempt": 0,
    "nextRetryTimeStamp": 0,
    "name": "addNewPipeline"
  },
  "Names2PgStage1wholecopy8396290d-163e-4ec6-9371-5f09baf29a23": {
    "pipelineId": "Names2PgStage1wholecopy8396290d-163e-4ec6-9371-5f09baf29a23",
    "rev": "0",
    "user": "admin",
    "status": "STOPPED",
    "message": "Stopped while the pipeline was in RETRY state",
    "timeStamp": 1560759731119,
    "attributes": {
      "IS_REMOTE_PIPELINE": false,
      "RUNTIME_PARAMETERS": null,
      "INTERCEPTOR_CONFIGS": []
    },
    "executionMode": "STANDALONE",
    "metrics": null,
    "retryAttempt": 0,
    "nextRetryTimeStamp": 0,
    "name": "Names2PgStage1wholecopy8396290d-163e-4ec6-9371-5f09baf29a23"
  }
}

通过观察可以发现,这个json是有规律的,格式是固定的,所以解析并不难。

        JSONObject jsonObject = JSONObject.parseObject(result);

        Collection<Object> list=jsonObject.values();
        Iterator<Object> it= list.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            Map m=JSONObject.parseObject(obj.toString(),Map.class);
            String pipelineId=m.get("pipelineId").toString();
            Tasks tasks=new Tasks();
            tasks.setPipeline_id(pipelineId);
            List<Tasks> lists=tasksService.selectByTask(tasks);
            if(lists!=null && lists.size()>0){
                Tasks task=lists.get(0);
                task.setTask_status(m.get("status").toString());
                task.setCommitted_offsets(m.get("message")==null?""
                :m.get("message").toString());
                tasksService.editTask(task);
            }
        }

2、查询所有日志

在system分组下,参数可选,直接GET  /rest/v1/system/logs?endingOffset=-1

返回结果如下:

[
  {
    "timestamp": "2019-06-20 09:04:48,875",
    "s-user": "*admin",
    "s-entity": "hdp/hdpd32e5f16-4d10-439f-b5ad-4fbc29c78211",
    "s-runner": "",
    "thread": "Spool Directory Runner - 0",
    "s-stage": "",
    "severity": "DEBUG",
    "category": "ProductionSourceOffsetTracker",
    "message": "Saving offset {$com.streamsets.pipeline.stage.origin.spooldir.SpoolDirSource.offset.version$=1, SSTableExport-1.0-SNAPSHOT.jar={\"POS\":\"-1\"}} for pipeline hdpd32e5f16-4d10-439f-b5ad-4fbc29c78211"
  },
  {
    "timestamp": "2019-06-20 09:04:48,877",
    "s-user": "*admin",
    "s-entity": "hdp/hdpd32e5f16-4d10-439f-b5ad-4fbc29c78211",
    "s-runner": "",
    "thread": "Spool Directory Runner - 0",
    "s-stage": "",
    "severity": "DEBUG",
    "category": "DirectorySpooler",
    "message": "Polling for file, waiting '60000' ms"
  }
]

通过观察发现这个json也是有固定格式的,遍历解析就可以了

            JSONArray jsonArray = JSONArray.parseArray(result);
            for (Object obj : jsonArray) {
                JSONObject jsonObject = (JSONObject) obj;

                AlertLogs alertLogs=new AlertLogs();

                alertLogs.setSdc_id(sdc.getSdc_id());
                alertLogs.setSdc_name(sdc.getSdc_name());
                alertLogs.setSdc_ip(sdc.getSdc_ip());
                alertLogs.setSdc_port(sdc.getSdc_port());
                alertLogs.setLog_time(jsonObject.getDate("timestamp"));
                alertLogs.setMessage(jsonObject.getString("message"));
                alertLogs.setLog_level(jsonObject.getString("severity"));
                String entity=jsonObject.getString("s-entity");
                if(entity.contains("/")){
                    String[] arr=entity.split("/");
                    StringBuffer sb=new StringBuffer();
                    for(int i=0;i<arr.length-1;i++){
                        sb.append(arr[i]);
                    }
                    alertLogs.setPipeline_title(sb.toString());
                    alertLogs.setPipeline_id(arr[arr.length-1]);
                }
                alertLogsService.insert(alertLogs);
            }

 

3、查询streamsets的jmx信息

这个接口是在页面中调用的,swagger页面没有列出,地址 GET  /rest/v1/system/jmx

返回结果如下,结果特别长,这里列举一部分:

{
    "beans": [
        {
            "name": "metrics:name=sdc.pipeline.testcopya2cc2ed4-bd24-441a-9b09-6a2fdbb4b082.0.pipeline.batchInputRecords.meter",
            "modelerType": "com.codahale.metrics.jmx.JmxReporter$JmxMeter",
            "RateUnit": "events/second",
            "OneMinuteRate": 1.5702124778961105e-86,
            "FiveMinuteRate": 1.5921483231199352e-14,
            "FifteenMinuteRate": 0.015958339755563485,
            "MeanRate": 6.420727951968242,
            "Count": 79884
        },
        {
            "name": "metrics:name=jvm.threads.new.count",
            "modelerType": "com.codahale.metrics.jmx.JmxReporter$JmxGauge",
            "Value": 0
        },
        {
            "name": "metrics:name=sdc.pipeline.loalToTrash.0.stage.Directory_01.errorRecords.meter",
            "modelerType": "com.codahale.metrics.jmx.JmxReporter$JmxMeter",
            "RateUnit": "events/second",
            "OneMinuteRate": 0,
            "FiveMinuteRate": 0,
            "FifteenMinuteRate": 0,
            "MeanRate": 0,
            "Count": 0
        },
        {
            "name": "metrics:name=jvm.memory.pools.Metaspace.usage",
            "modelerType": "com.codahale.metrics.jmx.JmxReporter$JmxGauge",
            "Value": 0.9130996604846318
        },
        {
            "name": "metrics:name=sdc.pipeline.loalToTrash.0.stage.Directory_01.errorRecords.histogramM5",
            "modelerType": "com.codahale.metrics.jmx.JmxReporter$JmxHistogram",
            "50thPercentile": 0,
            "SnapshotSize": 1028,
            "Max": 0,
            "Mean": 0,
            "Min": 0,
            "75thPercentile": 0,
            "95thPercentile": 0,
            "98thPercentile": 0,
            "99thPercentile": 0,
            "999thPercentile": 0,
            "StdDev": 0,
            "Count": 2749
        }
]

通过观察发现这个json格式不统一,没有规律,所以只能分别遍历,通过name判断是哪些指标,然后对应解析,这里列举了一部分代码:

            if(name.equals(JmxEnum.OPERATING_SYSTEM)){
                metricSdcJmx.setMetric_name(JmxMetricNameEnum.ProcessCpuLoad);
                metricSdcJmx.setUsage(jsonObject.getDouble("ProcessCpuLoad"));
                metricSdcJmxService.insert(metricSdcJmx);
            }else if(name.equals(JmxEnum.THREADING)){
                metricSdcJmx.setMetric_name(JmxMetricNameEnum.ThreadCount);
                metricSdcJmx.setVcount(jsonObject.getInteger("ThreadCount"));
                metricSdcJmxService.insert(metricSdcJmx);

                metricSdcJmx.setMetric_name(JmxMetricNameEnum.PeakThreadCount);
                metricSdcJmx.setVcount(jsonObject.getInteger("PeakThreadCount"));
                metricSdcJmxService.insert(metricSdcJmx);

                metricSdcJmx.setMetric_name(JmxMetricNameEnum.TotalStartedThreadCount);
                metricSdcJmx.setVcount(jsonObject.getInteger("TotalStartedThreadCount"));
                metricSdcJmxService.insert(metricSdcJmx);
            }else if(name.equals(JmxEnum.CLASS_LOADING)){
                metricSdcJmx.setMetric_name(JmxMetricNameEnum.LoadedClassCount);
                metricSdcJmx.setVcount(jsonObject.getInteger("LoadedClassCount"));
                metricSdcJmxService.insert(metricSdcJmx);

                metricSdcJmx.setMetric_name(JmxMetricNameEnum.UnloadedClassCount);
                metricSdcJmx.setVcount(jsonObject.getInteger("UnloadedClassCount"));
                metricSdcJmxService.insert(metricSdcJmx);

                metricSdcJmx.setMetric_name(JmxMetricNameEnum.TotalLoadedClassCount);
                metricSdcJmx.setVcount(jsonObject.getInteger("TotalLoadedClassCount"));
                metricSdcJmxService.insert(metricSdcJmx);
            }

4、查询指定任务的运行metric

在manager分组下,需要pipelineId参数,GET  /rest/v1/pipeline/{pipelineId}/metrics

返回结果如下:

//主要的内容
{
  "version": "string",
  "gauges": {},
  "counters": {},
  "histograms": {},
  "meters": {},
  "timers": {}
}

//详细内容,部分
{
  "version": "4.0.0",
  "gauges": {
    "RuntimeStatsGauge.gauge": {
      "value": {
        "batchCount": 95,
        "idleBatchCount": 0,
        "timeOfLastReceivedRecord": 1557296520561,
        "lastBatchInputRecordsCount": 0,
        "lastBatchOutputRecordsCount": 0,
        "lastBatchErrorRecordsCount": 0,
        "lastBatchErrorMessagesCount": 0,
        "totalRunners": 1,
        "availableRunners": 1
      }
    },
。。。。
 "counters": {
    "custom.Directory_01.pending.files.0.counter": {
      "count": 0
    },
    。。
 "histograms": {
    "pipeline.errorRecordsPerBatch.histogramM5": {
      "count": 95,
      "max": 0,
      "mean": 0,
      "min": 0,
      "p50": 0,
      "p75": 0,
      "p95": 0,
      "p98": 0,
      "p99": 0,
      "p999": 0,
      "stddev": 0
    },
。。。。
},
  "meters": {
    "custom.Directory_01.spoolQueue.0.meter": {
      "count": 90,
      "m1_rate": 11.866331343607989,
      "m5_rate": 16.560799463327818,
      "m15_rate": 17.50688058809427,
      "m30_rate": 17.751728101390487,
      "h1_rate": 17.875433024825686,
      "h6_rate": 17.97917871834381,
      "h12_rate": 17.989586346833782,
      "h24_rate": 17.994792420114447,
      "mean_rate": 2.9818143805481996,
      "units": "events/second"
    },。。。
 "timers": {
    "pipeline.batchProcessing.timer": {
      "count": 95,
      "max": 5.009,
      "mean": 0.2708105263157895,
      "min": 0.003,
      "p50": 0.006,
      "p75": 0.009000000000000001,
      "p95": 5.005,
      "p98": 5.007160000000001,
      "p99": 5.009,
      "p999": 5.009,
      "stddev": 1.1221307457361267,
      "m15_rate": 17.512359692670998,
      "m1_rate": 11.9344832175679,
      "m5_rate": 16.576790580401955,
      "mean_rate": 3.1389838868870585,
      "duration_units": "seconds",
      "rate_units": "calls/second"
    },
。。。
}

通过观察发现,这个json也是不统一,没有规律,但是整体上分了几个部分,所以通过解析后,分别解析不同的部分

        JSONObject gauges= jsonObject.getJSONObject("gauges");
        Iterator gauges_it= gauges.entrySet().iterator();
        while(gauges_it.hasNext()) {
            Map.Entry<String, JSONObject> entry = (Map.Entry<String, JSONObject>) gauges_it.next();
            String key = entry.getKey();
            JSONObject json = entry.getValue();
            if (key.startsWith("RuntimeStatsGauge")) {
                JSONObject gauge=json.getJSONObject("value");
                MetricsPipeline metricsPipeline=new MetricsPipeline();
                metricsPipeline.setCollect_time(collect_time);
                metricsPipeline.setPipeline_id(pipelineId);
                metricsPipeline.setMetric_name(key+".lastBatchErrorMessagesCount");
                metricsPipeline.setVcount(gauge.getInteger("lastBatchErrorMessagesCount"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".timeOfLastReceivedRecord");
                metricsPipeline.setVcount(gauge.getInteger("timeOfLastReceivedRecord"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".idleBatchCount");
                metricsPipeline.setVcount(gauge.getInteger("idleBatchCount"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".lastBatchErrorRecordsCount");
                metricsPipeline.setVcount(gauge.getInteger("lastBatchErrorRecordsCount"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".lastBatchOutputRecordsCount");
                metricsPipeline.setVcount(gauge.getInteger("lastBatchOutputRecordsCount"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".availableRunners");
                metricsPipeline.setVcount(gauge.getInteger("availableRunners"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".lastBatchInputRecordsCount");
                metricsPipeline.setVcount(gauge.getInteger("lastBatchInputRecordsCount"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".totalRunners");
                metricsPipeline.setVcount(gauge.getInteger("totalRunners"));
                metricsPipelineService.insert(metricsPipeline);

                metricsPipeline.setMetric_name(key+".batchCount");
                metricsPipeline.setVcount(gauge.getInteger("batchCount"));
                metricsPipelineService.insert(metricsPipeline);
            }else if(key.startsWith("custom")){
                JSONObject gauge=json.getJSONObject("value");
                MetricsPipeline metricsPipeline=new MetricsPipeline();
                metricsPipeline.setCollect_time(collect_time);
                metricsPipeline.setPipeline_id(pipelineId);
                metricsPipeline.setMetric_name(key);
                metricsPipeline.setStatus(gauge.getString("Status"));
                metricsPipeline.setCurrent_stage(gauge.getString("Current Offset"));
                metricsPipeline.setThread_name(gauge.getString("Thread Name"));
                metricsPipeline.setCurrent_file(gauge.getString("Current File"));
                metricsPipelineService.insert(metricsPipeline);
            }

 

 

 

 

### 回答1: Fastjson是阿里巴巴的一个开源的Java库,可以用于解析和生成JSON数据。解析复杂JSON数据需要创建一个Java类来映射JSON数据的结构,然后使用Fastjson API将JSON字符串解析为Java对象。如果你想要解析一个复杂JSON数据,你可以尝试如下方法: 1. 定义一个Java类来映射JSON数据的结构。每一个字段对应一个键值对。 2. 使用Fastjson的API,如parseObject,将JSON字符串解析为一个Java对象。 3. 使用解析后的Java对象访问数据。 代码示例: ``` String json = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}"; //1. 定义一个Java类来映射JSON数据的结构 class User { private String name; private int age; private String city; //getters and setters } //2. 使用Fastjson的API,将JSON字符串解析为一个Java对象 User user = JSON.parseObject(json, User.class); //3. 使用解析后的Java对象访问数据 System.out.println(user.getName()); System.out.println(user.getAge()); System.out.println(user.getCity()); ``` ### 回答2: Fastjson是一个Java的解析JSON库,它快速、稳定、易用,可以处理各种复杂JSON数据结构。Fastjson解析速度非常快,可以提高程序的性能,大大减少了JSON数据解析与Java对象转换的时间,利用了Java语言的强大性能优势,使得Fastjson成为了一款非常受欢迎的JSON解析库之一。 Fastjson可以快速处理各种JSON数据格式,包括对象、数组、字符串、数字等,可以轻松地将JSON数据转换为Java对象或Map,也可以将Java对象转换为JSON字符串。Fastjson采用的是基于Bean的转换,即将JSON数据转换为Java对象时,会根据JSON数据自动创建Java对象,并将JSON数据中的字段映射到Java对象中对应的属性中。 Fastjson可以解析复杂JSON数据,例如包含嵌套对象和数组的JSON数据。Fastjson提供了很多高级的特性,例如自动类型识别、处理循环引用、支持序列化与反序列化、支持自定义序列化规则等,这些特性使得Fastjson在处理复杂JSON数据结构时更为灵活和可靠。 Fastjson还可以通过注解的方式来设置Java对象与JSON数据之间的映射规则,提高了程序的可维护性和可读性。通过注解可以自动设置Java属性与JSON字段之间的映射,也可以忽略不需要的属性,还可以自定义转换器来实现自定义的序列化与反序列化规则。 在实际开发中,Fastjson是一款非常实用的JSON解析库,它可以轻松地处理各种复杂JSON数据结构,提高程序的性能和可维护性,方便开发人员快速地开发出高质量的应用程序。 ### 回答3: Fastjson是一种高效且易于使用的Java JSON解析框架。它可以帮助Java开发人员快速地将JSON数据转换为Java对象,同时保持数据的完整性和准确性。 Fastjson支持解析不同复杂度的JSON数据,如简单JSON对象,嵌套的JSON对象,数组和嵌套的数组。为了解析复杂JSON数据,Fastjson提供了几种重要的功能和API: 1. JSON对象和JSON数组 对于一个复杂JSON数据,它可能包含许多嵌套的JSON对象和JSON数组。Fastjson提供了JSONObject和JSONArray类,可以帮助我们处理这些结构数据。我们可以使用getJSONObject()和getJSONArray()方法从JSONObject或JSONArray中获取子对象和子数组。 2.反序列化 反序列化是将JSON数据转换为Java对象的过程。Fastjson提供了一个JSON.parseObject()方法,可以将JSON字符串转换为Java对象。例如,我们可以使用下面的代码将一个复杂JSON字符串解析为一个Java对象: String jsonString = "{\"name\":\"John\",\"age\":30,\"address\":{\"city\":\"New York\"}}"; Person person = JSON.parseObject(jsonString, Person.class); 3.注解 Fastjson提供了一些注解来帮助Java开发人员更灵活地控制对象的转换和序列化过程。例如,@JSONField注解可以指定JSON字段的名称和顺序,@JSONCreator注解可以指定一个特殊的构造函数,用于反序列化操作。 4.特殊对象转换器 有些复杂JSON数据可能包含自定义的对象类型,无法直接通过Fastjson的默认转换器进行序列化和反序列化。Fastjson提供了ObjectSerializer和ObjectDeserializer接口,可以实现自定义的对象转换器。 总之,Fastjson是一种非常强大、稳定和易于使用的JSON框架,可以帮助Java开发人员快速高效地处理复杂和大数据量的JSON数据。它的灵活性和可定制性也让它成为许多企业级应用程序中首选的JSON解析库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值