2023년 9월 26일 화요일

convert ip to decimal

IP 주소를 십진수로 바꿔주는 런타임 필드 쿼리.
GET testindex/_search
{
  "runtime_mappings": {
    "ip_pow": {
      "type": "long",
      "script": """
        def result = 0;
        def pow = 3;
        for (i in doc['message.keyword'].value.splitOnToken('.')) {
          result += Integer.parseInt(i) * Math.pow(256, pow);
          pow -= 1;
        }
        emit(result);
      """
    }
  },
  "aggs": {
    "ip_pow": {
      "terms": {
        "field": "ip_pow"
      }
    }
  }
}

1.2.3.4와 192.168.56.1의 십진수는 각각 16,909,060과 2,147,483,647.
{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "testindex",
        "_id": "1",
        "_score": 1,
        "_source": {
          "message": "1.2.3.4"
        }
      },
      {
        "_index": "testindex",
        "_id": "2",
        "_score": 1,
        "_source": {
          "message": "192.168.56.1"
        }
      }
    ]
  },
  "aggregations": {
    "ip_pow": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": 16909060,
          "doc_count": 1
        },
        {
          "key": 2147483647,
          "doc_count": 1
        }
      ]
    }
  }
}

같은 목적의 인제스트 쿼리.
POST _ingest/pipeline/_simulate
{
  "pipeline": {
    "processors": [
      {
        "script": {
          "source": """
            def result = 0;
            def pow = 3;
            for (i in ctx.message.splitOnToken('.')) {
              result += Integer.parseInt(i) * Math.pow(256, pow);
              pow -= 1;
            }
            ctx.ip_pow = result;
          """
        }
      }
    ]
  },
  "docs": [
    {
      "_source": {
        "message": "1.2.3.4"
      }
    },
    {
      "_source": {
        "message": "192.168.56.1"
      }
    }    
  ]
}

런타임 필드 쿼리와 같은 결과.
{
  "docs": [
    {
      "doc": {
        "_index": "_index",
        "_id": "_id",
        "_version": "-3",
        "_source": {
          "message": "1.2.3.4",
          "ip_pow": 16909060
        },
        "_ingest": {
          "timestamp": "2023-09-26T02:25:23.2154284Z"
        }
      }
    },
    {
      "doc": {
        "_index": "_index",
        "_id": "_id",
        "_version": "-3",
        "_source": {
          "message": "192.168.56.1",
          "ip_pow": 2147483647
        },
        "_ingest": {
          "timestamp": "2023-09-26T02:25:23.2154284Z"
        }
      }
    }
  ]
}

로그스태시를 이용한 쿼리.
ruby {
 code => '
  result = 0
  pow = 3
  for i in event.get("message").split(".")
   result += i.to_i * (256 ** pow)
   pow -= 1
  end
  event.set("ip_pow", result)
 '
}

192.168.56.1의 값이 다르다.
[2023-09-26T11:52:27,105][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
{
     "ip_pow" => 16909060,
    "message" => "1.2.3.4"
}
{
     "ip_pow" => 3232249857,
    "message" => "192.168.56.1"
}

filebeat를 이용한 쿼리.
processors:
  - script:
      lang: javascript
      source: >
        function process(evt) {
          var result = 0;
          var pow = 3;
          var msg = evt.Get("message").split(".");
          for (var i = 0; i < msg.length; i++) {
            result += parseInt(msg[i]) * Math.pow(256, pow);
            pow -= 1;
          }
          evt.Put("ip_pow", result);
        }

로그스태시와 같은 결과. 
{
  "@timestamp": "2023-09-26T03:19:29.112Z",
  "@metadata": {
    "beat": "filebeat",
    "type": "_doc",
    "version": "8.4.1"
  },
  "message": "1.2.3.4",
  "ip_pow": 16909060
}
{
  "@timestamp": "2023-09-26T03:19:29.113Z",
  "@metadata": {
    "beat": "filebeat",
    "type": "_doc",
    "version": "8.4.1"
  },
  "ip_pow": 3232249857,
  "message": "192.168.56.1"
}

계산기 두드려보면 192.168.56.1의 십진수는 3,232,249,857이 맞다. 런터임 필드랑 인제스트 쿼리 왜 이러지? 구분만 되면 상관 없나? 참고로 스플렁크는 이렇게.


댓글 없음:

댓글 쓰기

크리에이티브 커먼즈 라이선스