• 在Fitnesse用例中获取ELK日志


    概述

    在执行一条隔了几个项目的全流程的接口自动化用例时,往往会遇到一个问题。
    如果用例执行失败,该从哪个服务的日志开始定位问题。
    以往的解决办法:回忆一段时间,理清业务流程后,才开始逐个对服务的日志进行排查。
    这个办法没有问题,但是很耗时。

    新方法

    现在很多公司都是用ELK来查看日志。它也提供了sdk,来设计自己的检索功能。
    我这里就利用了ELK的sdk新建了一个服务,提供了一些接口,对access、debug、extra以及error日志进行检索。
    在Fitnesse中利用这些接口,创建了一些关键字,来获取日志。

    好处

    1. 在自动化用例编写和调试时,就将检索日志的关键字保留下来
    2. 针对access日志,将需要关注的接口,保留下来
    3. ......

    核心实现

    依赖

    <properties>     
            <elasticsearch>7.14.0</elasticsearch>     
        </properties>
     <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>${elasticsearch}</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-client</artifactId>
                <version>${elasticsearch}</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <version>${elasticsearch}</version>
            </dependency>
    

    获取client

     //创建HttpHost
            
           HttpHost host = new HttpHost("elasticsearch_Ip",9200);
    
    
                     // 创建RestClientBuilder
            RestClientBuilder builder = RestClient.builder(host);
    
                     // 创建RestHighLevelClient
            RestHighLevelClient client = new RestHighLevelClient(builder);
    

    获取日志

    /*
     * @name: queryAccessLog
     * @description: TODO
     * @param fromTime 用例执行开始时间
     * @param size 日志记录条数
     * @param env 测试环境
     * @param filterOptions  过滤条件
     * #格式说明 
    * # a=b;c;d|e=f|g=h
    * # 表示检索三个字段a,e,g 并且是“与”的关系
    * # 其中b,c,d是字段a的匹配值,是“或“的关系
     * @return: java.util.List<java.lang.String>
     * @date: 2021/9/18 4:41 下午
     * @auther: hch
     *
    */
     public List<String> queryAccessLog(String fromTime, String size, String env, String filterOptions) {
            logger.debug("fromTime:{},size:{},env:{},filterOptions:{}",fromTime,size,env,filterOptions);
            List<String> contents=new ArrayList<>();
            logger.info("tomcat_code_access.log-begin");
            String index = "tomcat_code_access.log-" + GetTime.getCurrentTimeWithFormat("yyyy.MM.dd");
            if(!exists(index)){
                logger.debug("index does not exist");
                contents.add("index does not exist");
                //close();
                return contents;
            }else{
                logger.debug("index exists");
            }
            SearchResponse searchResponse = getLog(fromTime,size,env,filterOptions, index);
            if(null !=searchResponse){
                SearchHits hits = searchResponse.getHits();
                SearchHit[] searchHits = hits.getHits();
                for (SearchHit hit : searchHits) {
                    Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                    //access_req_params
                    //access_res_params
                    //project_name
                    //@timestamp
    
                    String access_req_params = (String) sourceAsMap.get("access_req_params");
                    String access_res_params = (String) sourceAsMap.get("access_res_params");
                    String project_name = (String) sourceAsMap.get("project_name");
                    String access_url=(String) sourceAsMap.get("access_url");
                    String time = (String) sourceAsMap.get("@timestamp");
                    //String hostName = String.valueOf(JSONPath.read(jsonObjectString,"$.host.name"));
    
                    StringBuffer sb = new StringBuffer();
                    sb.append(DateLocalUtcUtil.utcToLocal(time)).append(" : ")
                            .append(project_name).append(" : ")
                            .append(access_url).append(" : ")
                            .append(access_res_params).append(" : ")
                            .append(access_req_params);
                    contents.add(sb.toString());
                }
            }
            logger.info("tomcat_code_access.log-end");
            return contents;
        }
    
     private boolean exists(String index) {
            GetIndexRequest request = new GetIndexRequest(index);
            try {
                return client.indices().exists(request, RequestOptions.DEFAULT);
            } catch (IOException e) {
                logger.info(e.getMessage());
                e.printStackTrace();
               // this.close();
                return false;
            }
        }
    
    private SearchResponse getLog(String fromTime,String size,String env,String filterOptions, String index) {
    
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("host.name", "*" + env + "*"));
            if (!StringUtils.equals("null", fromTime)) {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("@timestamp")
                        .from(DateLocalUtcUtil.localToUtc(fromTime))
                );
            } else {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("@timestamp")
                        .from(DateLocalUtcUtil.localToUtc(GetTime.getAnyMinuteOfCurrentHourWithFormat(DateFormatConstant.DATA_TIME_FROMAT, "-5")))
                );
            }
    
            Map<String,String> paramsMap=filterOptionsToMap(filterOptions);
            logger.debug("filterOptions:{}", JSONObject.toJSONString(paramsMap));
    
            for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (StringUtils.contains(value, ";")) {
                    String[] values = StringUtils.split(value, ";");
                    BoolQueryBuilder bqb = QueryBuilders.boolQuery();
                    for (String s_value : values) {
                        bqb.should(QueryBuilders.matchQuery(key, s_value));
                    }
                    boolQueryBuilder.filter(bqb);
                } else {
                    boolQueryBuilder.filter(QueryBuilders.matchQuery(key, value));
                }
            }
    
    
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(boolQueryBuilder);
            sourceBuilder.sort(new FieldSortBuilder("@timestamp").order(SortOrder.DESC));
            if (!StringUtils.equals("null", size)) {
                sourceBuilder.from(0);
                sourceBuilder.size(Integer.valueOf(size));
            } else {
                sourceBuilder.from(0);
                sourceBuilder.size(100);
            }
            sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
    
    
            SearchRequest searchRequest = new SearchRequest(index);
            searchRequest.source(sourceBuilder);
    
            try {
                return client.search(searchRequest, RequestOptions.DEFAULT);
            } catch (IOException e) {
                logger.info(e.getMessage());
                e.printStackTrace();
                return null;
            }finally {
               // close();
            }
        }
    

    API参考

    1. Index Exists API
    2. Search API
    3. Building Queries

    资源参考

    https://blog.csdn.net/ass23313/article/details/94627725
    https://www.cnblogs.com/reycg-blog/p/9946821.html
    https://blog.csdn.net/qq_34624315/article/details/81041479
    https://www.jianshu.com/p/b0197c6ff895

    Fitnesse关键字

    当前的设计思路是,通过http请求上面的服务,获取到数据后,打印到fitnesse的执行日志中。

    public class EsFixture {
        private final static Logger logger = LoggerFactory.getLogger(EsFixture.class);
        private RestTemplate rest;
        private String DEBUG_URL="http://ip:port/elk/queryDebugLog";
        private String ACCESS_URL="http://ip:port/elk/queryAccessLog";
        private String EXTRA_URL="http://ip:port/elk/queryExtraLog";
        private String ERROR_URL="http://ip:port/elk/queryErrorLog";
    
        public EsFixture(){
            rest = RestContext.getInstance().restTemplate;
        }
    
        public int queryDebugLog(Map<String, String> paramsMap){
            List<String> list= this.postFormForObject(DEBUG_URL,null,paramsMap);
            logger.info("debug log - begin");
            for(String s:list){
                logger.info(s);
            }
            logger.info("debug log - end");
            return list.size();
        }
    
        public int queryAccessLog(Map<String, String> paramsMap){
            List<String> list= this.postFormForObject(ACCESS_URL,null,paramsMap);
            logger.info("access log - begin");
            for(String s:list){
                logger.info(s);
            }
            logger.info("access log - end");
            return list.size();
        }
    
        public int queryErrorLog(Map<String, String> paramsMap){
            List<String> list= this.postFormForObject(ERROR_URL,null,paramsMap);
            logger.info("error log - begin");
            for(String s:list){
                logger.info(s);
            }
            logger.info("error log - end");
            return list.size();
        }
    
        public int queryExtraLog(Map<String, String> paramsMap){
            List<String> list= this.postFormForObject(EXTRA_URL,null,paramsMap);
            logger.info("extra log - begin");
            for(String s:list){
                logger.info(s);
            }
            logger.info("extra log - end");
            return list.size();
        }
    
    
        private List<String> postFormForObject(String url, Map<String, String> headermap, Map<String, String> paramsmap) {
            MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
            if (null != paramsmap) {
                for (Map.Entry<String, String> entry : paramsmap.entrySet()) {
                    if(!"null".equals(entry.getValue().toLowerCase().trim())){
                        postParameters.add(entry.getKey(), entry.getValue());
                    }
                }
            }
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/x-www-form-urlencoded; charset=UTF-8");
            headers.setContentType(type);
            //headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            if (null != headermap) {
                for (Map.Entry<String, String> entry : headermap.entrySet()) {
                    headers.add(entry.getKey(), entry.getValue());
                }
            }
            HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(postParameters, headers);
            Map<String,Object> map = this.rest.postForObject(url, formEntity, Map.class);
            List<String> list= (List<String>)map.getOrDefault("data",new ArrayList<String>());
            return list;
        }
    }
    

    用例执行

    fitnesse执行日志

    本文来自博客园,作者:月色深潭,交流群:733423266,转载请注明原文链接:https://www.cnblogs.com/moonpool/p/15309421.html

  • 相关阅读:
    PL/SQL 导入excel表格到oracle数据表
    浏览器进不去网站解决方案
    Tomcat安装后启动一闪而过
    数据库系统Informix为例,介绍改善用户查询计划的方法。
    使用 PREPARE 的几个注意点
    mysqld服务器如何查看使用变量的值
    sessions 表的架构过程
    Apache和mysql的安装设置
    使用SimpleXML应该注意的问题有哪些?
    php phpeclipse + xampp 配置安装过程
  • 原文地址:https://www.cnblogs.com/moonpool/p/15309421.html
Copyright © 2020-2023  润新知