{
    "componentChunkName": "component---src-templates-blog-template-js",
    "path": "/elastic-open-data-api/",
    "result": {"data":{"cur":{"id":"14d02f5d-8a45-5d02-a388-e0abc2a9a2a7","html":"<h2 id=\"1-공공데이터-api-준비\" style=\"position:relative;\"><a href=\"#1-%EA%B3%B5%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0-api-%EC%A4%80%EB%B9%84\" aria-label=\"1 공공데이터 api 준비 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 공공데이터 api 준비</h2>\n<p>일단 먼저 원하는 공공데이터 api를 <a href=\"https://www.data.go.kr/\">공공데이터 포털</a>에서 확인할 수 있다. 여기서 자신이 원하는 다양한 공공데이터를 찾을 수 있고, csv 형태의 파일 데이터나 api 형식으로 제공받을 수 있는데 이 포스트에서는 실제 프로젝트 진행 중에 사용했던 공공데이터 api를 기준으로 설명할 것이다.<br>\n<a href=\"https://www.data.go.kr/data/15012964/openapi.do\">국토교통부_공동주택 에너지 사용 정보</a> api로 api를 호출하면 xml 형태의 데이터를 반환해준다.</p>\n<h2 id=\"2-데이터-전처리\" style=\"position:relative;\"><a href=\"#2-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC\" aria-label=\"2 데이터 전처리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 데이터 전처리</h2>\n<p>Filebeat가 파일을 읽어서 logstash로 보낼 때, 보통 csv 파일을 읽도록 하는 것이 편하기 때문에 Spring 환경에서 api를 호출하면서 xml 형태의 호출 결과를 csv 파일 형식으로 저장하도록 설정했다.<br>\n(<a href=\"https://www.elastic.co/guide/en/logstash/current/plugins-filters-xml.html\">Xml filter plugin</a>을 사용해서 Logstash에서 filter 설정을 하는 방법도 있다.)</p>\n<p>공공데이터 api 호출 방법은 <a href=\"https://www.data.go.kr/data/15012964/openapi.do\">국토교통부_공동주택 에너지 사용 정보</a> 하단에 샘플 코드를 제공하고 있어서 이를 활용해서 api 호출을 쉽게 할 수 있고, xml 호출 결과를 csv 파일로 변환하는 방법은 xsl 파일을 이용해서 csv 형태의 스타일로 바꿔서 파일을 저장하는 방식으로 진행했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">xmlToCsv</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> xml<span class=\"token punctuation\">,</span> <span class=\"token class-name\">String</span> apiName<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">Exception</span><span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">File</span> stylesheet <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">File</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"src/main/resources/data/\"</span> <span class=\"token operator\">+</span> apiName <span class=\"token operator\">+</span> <span class=\"token string\">\"Style.xsl\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token class-name\">DocumentBuilderFactory</span> factory <span class=\"token operator\">=</span> <span class=\"token class-name\">DocumentBuilderFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">newInstance</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">DocumentBuilder</span> builder <span class=\"token operator\">=</span> factory<span class=\"token punctuation\">.</span><span class=\"token function\">newDocumentBuilder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Document</span> document <span class=\"token operator\">=</span> builder<span class=\"token punctuation\">.</span><span class=\"token function\">parse</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">InputSource</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">StringReader</span><span class=\"token punctuation\">(</span>xml<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token class-name\">StreamSource</span> stylesource <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">StreamSource</span><span class=\"token punctuation\">(</span>stylesheet<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Transformer</span> transformer <span class=\"token operator\">=</span> <span class=\"token class-name\">TransformerFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">newInstance</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">newTransformer</span><span class=\"token punctuation\">(</span>stylesource<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Source</span> source <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">DOMSource</span><span class=\"token punctuation\">(</span>document<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Result</span> outputTarget <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">StreamResult</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">FileOutputStream</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"src/main/resources/data/\"</span> <span class=\"token operator\">+</span> apiName <span class=\"token operator\">+</span> <span class=\"token string\">\".csv\"</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        transformer<span class=\"token punctuation\">.</span><span class=\"token function\">transform</span><span class=\"token punctuation\">(</span>source<span class=\"token punctuation\">,</span> outputTarget<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span></code></pre></div>\n<p>[참고 : <a href=\"https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java\">https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java</a>]</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token prolog\">&lt;?xml version=\"1.0\"?></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>stylesheet</span> <span class=\"token attr-name\">version</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>1.0<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\"><span class=\"token namespace\">xmlns:</span>xsl</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>http://www.w3.org/1999/XSL/Transform<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>output</span> <span class=\"token attr-name\">method</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">omit-xml-declaration</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>yes<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">indent</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>no<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>template</span> <span class=\"token attr-name\">match</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>/<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\nreqDate,kaptCode,helect,hgas,hheat,hwaterCool\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>for-each</span> <span class=\"token attr-name\">select</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>//item<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>value-of</span> <span class=\"token attr-name\">select</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>concat(kaptCode, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, helect, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, hgas, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, hheat, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, hwaterCool, <span class=\"token punctuation\">'</span><span class=\"token entity\" title=\"&#xA;\">&amp;#xA;</span><span class=\"token punctuation\">'</span>)<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token namespace\">xsl:</span>for-each</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token namespace\">xsl:</span>template</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token namespace\">xsl:</span>stylesheet</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>위와 같은 형태의 xsl 파일을 이용해서 원하는 값들만 csv 스타일로 지정할 수 있다.<br>\n그러면 다음과 같은 xml 형식의 응답 데이터들 중 원하는 값들만 csv 파일에 저장할 수 있다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 103.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAABYlAAAWJQFJUiTwAAACa0lEQVQ4y6WUiY7bNhCG9f6vmKKb9aG1dZHifYlfQXnXidCmMVoCQ0qcmZ//HGTX9z3zPGOMYVkW2v/1euV6uezrNE0YbdBa/1KUUk/p1nXFWov3/mkgpUSskqYTYsYFj3Nut2trsw0h4KwleEdKiRjjLl1Tto+mbCybcnf2jhg8cvzAB/fUP8GcxTqPcomfR9cMGyvnPUZrcgpYa9BK7fur0gRrcFrh3COKBiqlwIWEsIVcNrbtIV3ZKtYYslaEVLgLj/GZ10el1h/S5Vp3NmldcTHvgDGVh2mtbPXo8E9yCNk7iw+BmDMxBPIWSfmRx5bPJ49P56/QvqTttZx653DB0Y39BSHEnj9tDKtWWG9ZlcJYS0oRH/y+5hgPB3yNnDM5pZ1IN00zwzCijcUbg5gFWln0siAXgZR2X8Mq8VqT8oPlz6wPIbdJm4S+DeRhoCQorSbesrmEj1DbpBXZBla1kXM5AB6KknIhpEyyDtEPuHlGjhPLorBiwUpJKRsl5wObXxWoy6UQcyGFgrjcsOPIfBuZpxkxT6xSE7TFLQsl5X8F+wTcdsBoPettIoWHU9kruHsfu+43LdS1cMPnyaVUZD/Qv39wfj+jhCYay1Z/D/QEdDHtPVi3jXZr9DDTf79wOl2Rg8Cvmsp/AawNENRt4H6+M7R8Sr3nrdb/A3gfkdee2/nG/TrgFvkoSN5ey+ExZFg/7si3N07vF97+PDF+vyBPZ6KLrwHaBvhZlEZCnK+s58telG9/vDFfR+T7O9741wBNiPiY8doj+gmv3eERqLvUl8AeN6U1dtpwYiUo/Xzj/vbqvViUvwAEumjH43YjgAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"xml-example.png\"\n        title=\"xml-example.png\"\n        src=\"/static/f401e36cfcfc150b566dc4489bfdb353/37523/xml-example.png\"\n        srcset=\"/static/f401e36cfcfc150b566dc4489bfdb353/e9ff0/xml-example.png 180w,\n/static/f401e36cfcfc150b566dc4489bfdb353/f21e7/xml-example.png 360w,\n/static/f401e36cfcfc150b566dc4489bfdb353/37523/xml-example.png 720w,\n/static/f401e36cfcfc150b566dc4489bfdb353/302a4/xml-example.png 1080w,\n/static/f401e36cfcfc150b566dc4489bfdb353/f1c64/xml-example.png 1390w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span><br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 624px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 81.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACRklEQVQ4y3WTuW/bMBTGNQZIh9qe0jUZfOimqJuHJMpxUKBoUfQAOhRFlqD///4V7zlW5MQdHmjJ1A/fQXpffz/hx+Nf/Hz8i+9/nvD51yO6h08omxaV0qja8ynbt++mUQaeUCNS5SCUgzp8gfn4DZUdYXoH3Tk02qLtetTG8qje8bMeRjSmg90feG1NjyCM4AmRIY4TpEkKbXvY3vEf19fvcHV1hZubDzBuhOoH1Nrwx6mU8KMAQRQijCMEYYggCLDdbuEJWSARErSaYc+qdkEEz/N4FosF7LBHrSyqRkOZHkXZ8O9UZNis1wyi2e128NIsR5xmEFkO0++h7IBdEE7A5XLFQDPco2oUR0B5qc4hy0tsNxsGnYYVxql8Bo7Q/Qg/jGfAJay7Z0DZKJR1i1oZziyKYmy3l4BCgpQSjGzPLRPQUAG6Y5uyqGCHe4ZuZupeWT4CSQWpmStcLJecq+5GVlVUzdGydUhENoHeKCTLBKM5K4UsD3tYd2CVBCSFnLXvXwYmbFmyEsrxdSndeEDz3HJe1hxL3Rqs1+vJ7mSZmnppebyosHNHRVMpreHn09k7y/AMSNaoFH+mcLXiW0MQOjZ8xRqNzh2Q5cVZMW+AF1teHc/hqZBWdwzX/z2HDDy2TDDKaw58v1ig3z8wgNRRlnRkaC8BN5uXm8JXr6pqxEmCoizRtAoyL5CkKe7u7nB7e8ubyqqGzHNImSOTkte8KJEKgSiKEMfxNN4RICAyiTAMWTaFfdoQPb/zff/V0D6f987nH6HC+UYuar6NAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"csv-example.png\"\n        title=\"csv-example.png\"\n        src=\"/static/4852c8e7c3d091af1a38fa4440ef5157/39c09/csv-example.png\"\n        srcset=\"/static/4852c8e7c3d091af1a38fa4440ef5157/e9ff0/csv-example.png 180w,\n/static/4852c8e7c3d091af1a38fa4440ef5157/f21e7/csv-example.png 360w,\n/static/4852c8e7c3d091af1a38fa4440ef5157/39c09/csv-example.png 624w\"\n        sizes=\"(max-width: 624px) 100vw, 624px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>(reqDate의 경우는 응답 데이터에는 없지만 따로 필요하기 때문에 위 <code class=\"language-text\">xmlToCsv()</code> 메소드를 수정해서 추가했습니다.)</p>\n<hr>\n<h2 id=\"3-elasticsearch-및-kibana-실행\" style=\"position:relative;\"><a href=\"#3-elasticsearch-%EB%B0%8F-kibana-%EC%8B%A4%ED%96%89\" aria-label=\"3 elasticsearch 및 kibana 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Elasticsearch 및 Kibana 실행</h2>\n<p>앞서 포스트에서 진행한 것처럼 Elastic Stack 전부 다 설치 완료되었다고 생각하고 같은 방법으로 실행하면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew services start elastic/tap/elasticsearch-full\nbrew services start elastic/tap/kibana-full</code></pre></div>\n<p>위 명령어로 Elasticsearch와 Kibana를 백그라운드에서 실행해주고, 이제 Logstash 설정으로 넘어가면 된다.</p>\n<hr>\n<h2 id=\"4-logstash-설정-및-실행\" style=\"position:relative;\"><a href=\"#4-logstash-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"4 logstash 설정 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Logstash 설정 및 실행</h2>\n<p>실행하기 전에 인덱싱하기 적절하게 필터링을 위한 설정 파일(<code class=\"language-text\">logstash-sample.conf</code>)을 수정하여 필터링 설정을 할 수 있는데 Homebrew를 통해 설치한 경우에는 다음과 같은 경로에 Logstash의 설정 파일들이 위치해 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token builtin class-name\">cd</span> /opt/homebrew/etc/logstash\n<span class=\"token function\">vi</span> logstash-sample.conf</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># Sample Logstash configuration for creating a simple</span>\n<span class=\"token comment\"># Beats -> Logstash -> Elasticsearch pipeline.</span>\ninput <span class=\"token punctuation\">{</span>\n  beats <span class=\"token punctuation\">{</span>\n    port <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">5044</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\noutput <span class=\"token punctuation\">{</span>\n  elasticsearch <span class=\"token punctuation\">{</span>\n    hosts <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"http://localhost:9200\"</span><span class=\"token punctuation\">]</span>\n    index <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}\"</span>\n    <span class=\"token comment\">#user => \"elastic\"</span>\n    <span class=\"token comment\">#password => \"changeme\"</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>처음 설정 파일을 열어보면 위와 같이 파일이 구성되어 있는데 여기서 <code class=\"language-text\">filter</code>를 추가하여 필터링 설정을 할 수 있다.<br>\n“message” 필드를 통해 데이터들이 들어오고 csv 형태의 파일들은 ”,“를 기준으로 데이터들이 나뉘기 때문에 이를 이용해서 값들을 나누어주면 된다.<br>\n나뉜 값들은 이름을 지정해서 새로운 필드로 추가해주면 되고, 기본으로 제공하는 필요없는 필드들은 제거해주면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># Sample Logstash configuration for creating a simple</span>\n<span class=\"token comment\"># Beats -> Logstash -> Elasticsearch pipeline.</span>\ninput <span class=\"token punctuation\">{</span>\n  beats <span class=\"token punctuation\">{</span>\n    port <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">5044</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\nfilter <span class=\"token punctuation\">{</span>\n  mutate <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">split</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"message\"</span>, <span class=\"token string\">\",\"</span><span class=\"token punctuation\">]</span>\n    add_field <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token string\">\"reqDate\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][0]}\"</span>\n      <span class=\"token string\">\"kaptCode\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][1]}\"</span>\n      <span class=\"token string\">\"helect\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][2]}\"</span>\n      <span class=\"token string\">\"hgas\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][3]}\"</span>\n      <span class=\"token string\">\"hheat\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][4]}\"</span>\n      <span class=\"token string\">\"hwaterCool\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][5]}\"</span>\n    <span class=\"token punctuation\">}</span>\n\n    remove_field <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"ecs\"</span>, <span class=\"token string\">\"host\"</span>, <span class=\"token string\">\"@version\"</span>, <span class=\"token string\">\"agent\"</span>, <span class=\"token string\">\"log\"</span>, <span class=\"token string\">\"tags\"</span>, <span class=\"token string\">\"input\"</span>, <span class=\"token string\">\"message\"</span><span class=\"token punctuation\">]</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\noutput <span class=\"token punctuation\">{</span>\n  elasticsearch <span class=\"token punctuation\">{</span>\n    hosts <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"http://localhost:9200\"</span><span class=\"token punctuation\">]</span>\n    index <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}\"</span>\n    <span class=\"token comment\">#user => \"elastic\"</span>\n    <span class=\"token comment\">#password => \"changeme\"</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>이렇게 설정한 후에는 해당 디렉토리에서 다음 명령어를 통해 <strong>Logstash</strong>를 실행한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">logstash -f logstash-sample.conf</code></pre></div>\n<hr>\n<h2 id=\"5-filebeat-설정-및-실행\" style=\"position:relative;\"><a href=\"#5-filebeat-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"5 filebeat 설정 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. Filebeat 설정 및 실행</h2>\n<p>실행하기 전에 설정 파일(<code class=\"language-text\">filebeat.yml</code>)을 수정하여 <strong>input</strong>과 <strong>output</strong>에 대한 설정을 할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token builtin class-name\">cd</span> /opt/homebrew/etc/filebeat\n<span class=\"token function\">vi</span> filebeat.yml</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># ============================== Filebeat inputs ===============================</span>\n\nfilebeat.inputs:\n\n<span class=\"token comment\"># Each - is an input. Most options can be set at the input level, so</span>\n<span class=\"token comment\"># you can use different inputs for various configurations.</span>\n<span class=\"token comment\"># Below are the input specific configurations.</span>\n\n<span class=\"token comment\"># filestream is an input for collecting log messages from files.</span>\n- type: filestream\n\n  <span class=\"token comment\"># Change to true to enable this input configuration.</span>\n  enabled: <span class=\"token boolean\">true</span>\n\n  <span class=\"token comment\"># Paths that should be crawled and fetched. Glob based paths.</span>\n  paths:\n    - /Users/jfe/Desktop/Carbon_Tracker/Server/carbonTracker/src/main/resources/data/aptEnergy.csv</code></pre></div>\n<p>설정 파일에서 input 부분에서 filestream 타입의 input을 허용해주기 위해 enabled: true로 바꿔주고, 읽기 원하는 데이터 파일의 경로를 지정해주면 된다.<br>\n그 다음, Filebeat -> Logstash -> Elasticsearch -> Kibana 순서로 데이터를 보내기 때문에 Elasticsearch로의 output 부분은 전부 주석 처리해주고, Logstash로의 output 부분 주석들을 해제해주면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># ---------------------------- Elasticsearch Output ----------------------------</span>\n<span class=\"token comment\"># output.elasticsearch:</span>\n  <span class=\"token comment\"># Array of hosts to connect to.</span>\n  <span class=\"token comment\"># hosts: [\"localhost:9200\"]</span>\n\n  <span class=\"token comment\"># Protocol - either `http` (default) or `https`.</span>\n  <span class=\"token comment\">#protocol: \"https\"</span>\n\n  <span class=\"token comment\"># Authentication credentials - either API key or username/password.</span>\n  <span class=\"token comment\">#api_key: \"id:api_key\"</span>\n  <span class=\"token comment\">#username: \"elastic\"</span>\n  <span class=\"token comment\">#password: \"changeme\"</span>\n\n<span class=\"token comment\"># ------------------------------ Logstash Output -------------------------------</span>\noutput.logstash:\n  <span class=\"token comment\"># The Logstash hosts</span>\n  hosts: <span class=\"token punctuation\">[</span><span class=\"token string\">\"localhost:5044\"</span><span class=\"token punctuation\">]</span></code></pre></div>\n<p>이렇게 설정한 후에는 해당 디렉토리에서 다음 명령어를 통해 <strong>Filebeat</strong>를 실행하면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">filebeat -e                 <span class=\"token comment\"># 일반적으로 실행 하는 경우</span>\nfilebeat -e -c filebeat.yml <span class=\"token comment\"># -c 옵션은 configuration 파일을 특정할 때 사용 (-c 사용안하면 default는 filebeat.yml)</span></code></pre></div>\n<hr>\n<h2 id=\"6-kibana에서-데이터-확인\" style=\"position:relative;\"><a href=\"#6-kibana%EC%97%90%EC%84%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%99%95%EC%9D%B8\" aria-label=\"6 kibana에서 데이터 확인 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. Kibana에서 데이터 확인</h2>\n<p><a href=\"http://localhost:5601\">http://localhost:5601</a> 에 접속하여 제대로 실행되었는지 확인하고, Index Patterns로 이동해서 index pattern을 설정하면 된다.<br>\n데이터가 정상적으로 수집되고 있으면 해당 index가 보여지고, 그 index를 기준으로 pattern을 만들 수 있다.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.55555555555556%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAACI0lEQVQoz12Ry0tUcQCFf/9GEUUgYU9qkS2yFhIFY7SwIMvAXovIGR/RUkKitdIqhNyViZtSE2Mc853N5DiDOlLNI3PseseZe+d178x9OV80yw4cDt+BszriYsMl6urqOXbiNLVHT3Gk9iT7DxymoeEKbe523O4OPO2duD2deNq7aPN00ubuoKPrKU03mjl4qIaaI8er27Pn6hHvfVMMjo3j8/qYm19gdm6e6c8zzAeWCUYl/OubrMZkElKWhJznRzLDz22FmKQQikTx+qaZnJqp5ifvFAIgpxvEN3dJSipJKYuatzAqFaRcAVktkjVMiqaFVbJwDJuybqBldcyyyf8SpgN6egU1cAs1+IDst1YKG4/Ij3xBeTaG2usl1zNGaugrno0QLSE/98MBboaXeBmK8XgoQetgjLvvYrS8jSLMCpjyKEwLcmu3KQfPg1+g9ryhUNdH8tUs6oU+pCfDiLlx9s1O0Lq8iJgc5vJEEPHQT2P/Kmd61xD3FhDmHljZAFbIhRZqprTShLHRjPZhkXz3R+QXo+S7R1AG/dz5HsYVWuJ6cAlXxM/zlTjXBuK4BiJcfR2hsX8dYVoOtlNBTmWIRmPEE7/I5Yo4VPj9Z5vw6hqbySTWnoNtmsg7MrF4grKm49gOZV2v8tbWFrZpIEx7D8tyKJVKaJpetfHvBE1nZydFOqOQSqUpFvVqt5vOkE5nUNQslmWTUdQqp1K75AsF/gLyBwP70vVXoAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"kibana-main.png\"\n        title=\"kibana-main.png\"\n        src=\"/static/cffc3594a69348a953cc88b2eee861a2/37523/kibana-main.png\"\n        srcset=\"/static/cffc3594a69348a953cc88b2eee861a2/e9ff0/kibana-main.png 180w,\n/static/cffc3594a69348a953cc88b2eee861a2/f21e7/kibana-main.png 360w,\n/static/cffc3594a69348a953cc88b2eee861a2/37523/kibana-main.png 720w,\n/static/cffc3594a69348a953cc88b2eee861a2/302a4/kibana-main.png 1080w,\n/static/cffc3594a69348a953cc88b2eee861a2/07a9c/kibana-main.png 1440w,\n/static/cffc3594a69348a953cc88b2eee861a2/9dbdb/kibana-main.png 2622w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span><br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABw0lEQVQoz4WS227aUBBF/alVVZVbAraxccDG7n/krW0kpERVHvsZfWreGkWloglgwMbgyzle1TGlAZSoI22NdKRZ3nvGWjcIaJh93rzv8Lau865h0Gh2KrXODHSzR7OlU6ufU2u0qSvVz49Uq51Vvd3pon2+vuHyasTH0Reurm/5NLphOp2yWq1YLJeEiwVlWXJYKbCWkqTcKQcEVF0zDBND17EsC13XaTUbfL+7IwwXzOch8zBku00pCrGTEDxFEb+jiMc4YpmmJEXBNI5Z5zma41zQ7w/w/Q+43hA/CBiPf7HZpuRFQV4Isixnm2ZVF0KwjmI2yYZSSFDmy5IiLyhliWbbPTodHcfpMxi4eJ7Hj/sHJk9zwmXEKoormJQlQpZIKRFCIqSs4qt1HK5EsywbJdf1GLguvu8znjwSZyWrREUtKlf7wcPhw7e9tF7PwTS7lTsFDYKA2WzGa3UK2L/9c6iAyqHa4x6orqxKxXvJxUug58i2Q8+5qGCnwOdBqv1VO/wf0LQcjK7DcOjjecO/kY8d7k55HPtVoG3bqF9HAYfDHfD+54Qkk2y2OWlWsEwy/K9j2rcPfBuvdx87OdAe+Ae8TPPBSX0A1gAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"kibana-index-pattern.png\"\n        title=\"kibana-index-pattern.png\"\n        src=\"/static/54d099ba85bdf4915154b2cbb1c970cf/37523/kibana-index-pattern.png\"\n        srcset=\"/static/54d099ba85bdf4915154b2cbb1c970cf/e9ff0/kibana-index-pattern.png 180w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/f21e7/kibana-index-pattern.png 360w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/37523/kibana-index-pattern.png 720w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/302a4/kibana-index-pattern.png 1080w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/07a9c/kibana-index-pattern.png 1440w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/60708/kibana-index-pattern.png 2872w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>생성한 index pattern에 대한 데이터들은 discover 메뉴로 가서 확인할 수 있다.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAACGklEQVQoz5WRW08TURSF59eChkDLzRB90N+ivnkBK4kSo/jAxRdIoNAiZdpaiEPbuU/ncmbOzGfOGZAXXzzJephk72/WWttYe/Gc+eYGc4+bLDVWWVx6UGN5nbX1pzRXntBorv/VYmOVuYVlHi2sMH+nxaU1misbGLdhipMW/O9TGxLIy/r7/VnAsx0LY+rNuLEcbMfHD2OiWYoQ9Q9kCXkh/61cImVJVUFRSG68lJ/jGMMPIn5bE8YThzBKyETBeGJjmn0syyJOUmZxQhwnREqzWgo6mTr0BwOSTAC1VcPzI6yxrQdELsllSffS5M3bd+wfHOK4Prbr47geE9vDmno4XkgQzjg5bTOe2mQip6wqRF5gBLOEJBXkRandVYA5vGZz6wN7e/s4XqDlej5T12fiBNheQJJmXJl9elem3q8UUOQYajiMYg1UUoNfvu6yudViMBwRhBGuH2inUzfUsCCKtRsF63QvSLOcLBNkQmCoQ8RJVgNzSVGUHJ+0aX3c5rR9hueHuNqlAgZMHB8viDSk07nA7A90skJXlmPYbog6TCEr0qygrOBqMKLV2ubg8Mcd7CHy2FadBqSZYDi6ptPtMktSDVSxjTgVJFmuncVpgZDQ6w/59HmHo6NjHde9Bzq+dngPVB22z87vgHX/xn136sJK6p13e7x89Zpvu9/rC3t1hwp2a/u4fqhjXvZMfl3f6D0pJWVZ8Qe/ayPgJZiQrQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"kibana-discover.png\"\n        title=\"kibana-discover.png\"\n        src=\"/static/954a25229ec00314a2a324ae7e59c5c2/37523/kibana-discover.png\"\n        srcset=\"/static/954a25229ec00314a2a324ae7e59c5c2/e9ff0/kibana-discover.png 180w,\n/static/954a25229ec00314a2a324ae7e59c5c2/f21e7/kibana-discover.png 360w,\n/static/954a25229ec00314a2a324ae7e59c5c2/37523/kibana-discover.png 720w,\n/static/954a25229ec00314a2a324ae7e59c5c2/302a4/kibana-discover.png 1080w,\n/static/954a25229ec00314a2a324ae7e59c5c2/07a9c/kibana-discover.png 1440w,\n/static/954a25229ec00314a2a324ae7e59c5c2/93ba6/kibana-discover.png 2874w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<hr>\n<p>공공데이터 api를 연동해서 얻은 데이터를 Filebeat -> Logstash -> Elasticsearch -> Kibana 순서로 수집하는 방법에 대해서 간단하게만 포스팅했는데, 그래서 데이터 전처리도 아직 완벽하게 하지 않았고 Kibana 사용 방법도 아직 제대로 알지는 못해서 프로젝트를 더 진행하면서 추후에 프로젝트 진행 과정과 회고와 함께 추가로 포스팅하겠습니다. (종프 화이팅,,)</p>\n<hr>\n<h2 id=\"-reference\" style=\"position:relative;\"><a href=\"#-reference\" aria-label=\" reference permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>📎 Reference</h2>\n<p><a href=\"https://www.data.go.kr/data/15012964/openapi.do\">https://www.data.go.kr/data/15012964/openapi.do</a><br>\n<a href=\"https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java\">https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java</a><br>\n<a href=\"https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-1/\">https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-1/</a><br>\n<a href=\"http://trandent.com/article/etc/detail/323366\">http://trandent.com/article/etc/detail/323366</a></p>\n<div class=\"table-of-contents\">\n<ul>\n<li><a href=\"#1-%EA%B3%B5%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0-api-%EC%A4%80%EB%B9%84\">1. 공공데이터 api 준비</a></li>\n<li><a href=\"#2-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC\">2. 데이터 전처리</a></li>\n<li><a href=\"#3-elasticsearch-%EB%B0%8F-kibana-%EC%8B%A4%ED%96%89\">3. Elasticsearch 및 Kibana 실행</a></li>\n<li><a href=\"#4-logstash-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\">4. Logstash 설정 및 실행</a></li>\n<li><a href=\"#5-filebeat-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\">5. Filebeat 설정 및 실행</a></li>\n<li><a href=\"#6-kibana%EC%97%90%EC%84%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%99%95%EC%9D%B8\">6. Kibana에서 데이터 확인</a></li>\n<li><a href=\"#-reference\">📎 Reference</a></li>\n</ul>\n</div>","excerpt":"1. 공공데이터 api 준비 일단 먼저 원하는 공공데이터 api를 공공데이터 포털에서 확인할 수 있다. 여기서 자신이 원하는 다양한 공공데이터를 찾을 수 있고, csv 형태의 파일 데이터나 api 형식으로 제공받을 수 있는데 이 포스트에서는 실제 프로젝트 진행 중에 사용했던 공공데이터 api를 기준으로 설명할 것이다. 국토교통부_공동주택 에너지 사용 정보 api로 api를 호출하면 xml 형태의 데이터를 반환해준다. 2. 데이터 전처리 Filebeat가 파일을 읽어서 logstash로 보낼 때, 보통 csv 파일을 읽도록 하는 것이 편하기 때문에 Spring 환경에서 api를 호출하면서 xml 형태의 호출 결과를 csv 파일 형식으로 저장하도록 설정했다. (Xml filter plugin을 사용해서 Logstash에서 filter 설정을 하는 방법도 있다.) 공공데이터 api 호출 방법은 국토교통부_공동주택 에너지 사용 정보 하단에 샘플 코드를 제공하고 있어서 이를 활용해서 api…","frontmatter":{"date":"April 09, 2022","title":"[Elastic] Elastic Stack + 공공데이터 api 활용","categories":"Database","author":"JFe","emoji":"🏢"},"fields":{"slug":"/elastic-open-data-api/"}},"next":{"id":"5b80011f-3dec-5ecf-ac2e-48a0a7d93009","html":"<h2 id=\"1-homebrew-설치\" style=\"position:relative;\"><a href=\"#1-homebrew-%EC%84%A4%EC%B9%98\" aria-label=\"1 homebrew 설치 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. Homebrew 설치</h2>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">/bin/bash -c <span class=\"token string\">\"<span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">curl</span> -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh<span class=\"token variable\">)</span></span>\"</span></code></pre></div>\n<p><strong>Homebrew</strong> 설치가 되어있지 않으면 터미널에서 위 명령어를 입력하여 설치할 수 있다.</p>\n<hr>\n<h2 id=\"2-elastic-tap-저장소-추가\" style=\"position:relative;\"><a href=\"#2-elastic-tap-%EC%A0%80%EC%9E%A5%EC%86%8C-%EC%B6%94%EA%B0%80\" aria-label=\"2 elastic tap 저장소 추가 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. elastic tap 저장소 추가</h2>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew tap elastic/tap</code></pre></div>\n<p>터미널에서 위 명령어를 통해 elastic 패키지 저장소를 추가할 수 있다.</p>\n<hr>\n<h2 id=\"3-elasticsearch-설치-및-실행\" style=\"position:relative;\"><a href=\"#3-elasticsearch-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"3 elasticsearch 설치 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Elasticsearch 설치 및 실행</h2>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew <span class=\"token function\">install</span> elastic/tap/elasticsearch-full</code></pre></div>\n<p>위 명령어로 <strong>Elasticsearch</strong>를 설치할 수 있고</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">elasticsearch</code></pre></div>\n<p>설치 완료 후에는 <code class=\"language-text\">elasticsearch</code> 명령어를 통해 <strong>Elasticsearch</strong>를 실행할 수 있다.<br>\n백그라운드에서 실행하고 싶으면 <code class=\"language-text\">elasticsearch</code> 명령어 대신 다음과 같은 명령어로 실행할 수도 있다.<br>\n(중단할 경우에는 <code class=\"language-text\">start</code> 대신에 <code class=\"language-text\">stop</code> 사용)</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew services start elastic/tap/elasticsearch-full</code></pre></div>\n<p>실행 후에는 <a href=\"http://localhost:9200\">http://localhost:9200</a> 에 접속하여 제대로 실행되었는지 확인할 수 있다.<br>\n다음과 같은 화면이 보이면 제대로 실행중인 경우<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.77777777777778%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACEUlEQVQ4y5WS22sTURDG848o+GSFPihotZHin9iEpCYVDX1QyIOPeW5zD/iiNZcGNreGktvuJmuyu8ne8pNzZEOrIOTAd/acmTPffDOzkVdHUaJv3/Hm+ISnB4ccvY5yHD3h+YuXHDw75NHjJ3shUiyWqVSqlMsVSqUy1VqNarVGsVginy9wdZXf4fLyinyhSOE/iACYponvefh4LB0Dl40wE+DLfZ8V8TyPTqdDu92m2+0yuB2g9BXefzoj+TEhkcqkSGfSZLNZ9LnOdrtFxPm+/w8iYpvP54xGIwzDIAgCTMukUW/QbrUlWs0WzUaTRqOBbduSULy7D2ETiITZFEWh3+szmU7QDR0XR2KfJQnDDKqqMp1OGQ6HWJbFj+Z3at9qXF9fU/9Zp16vy69QGkLYhF+0TJDJHoYKe72exE3rBssy+fL1M7FkjOR5gng6RuI8wdmHM05Tp8RSp8TTcS4uLshkMuRyOSlKEv6t8O7ujvF4LJ2mBY63Z8nbbSCnIyYsJq10FFmCKL076NO97aHpGupMlUnX6zULc87KXsnKPM+V8buhhJfFYsFsNkNTNXRNZzqZMh6N0cVd1aVvMpnIP2C1WTK3dDRTw9yYO3WS0HVdmVnTNGzbYrleoq80DHvB0v6FYS3QViqu5+6CQgI/EGKCh4RCoSB1HEf2UjzyfFfiz9nD9Z0HROH5fu9Cwt8UkJoixaCYjQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"elasticsearch-running.png\"\n        title=\"elasticsearch-running.png\"\n        src=\"/static/207f7ba00a136cecf490655820d2c416/37523/elasticsearch-running.png\"\n        srcset=\"/static/207f7ba00a136cecf490655820d2c416/e9ff0/elasticsearch-running.png 180w,\n/static/207f7ba00a136cecf490655820d2c416/f21e7/elasticsearch-running.png 360w,\n/static/207f7ba00a136cecf490655820d2c416/37523/elasticsearch-running.png 720w,\n/static/207f7ba00a136cecf490655820d2c416/302a4/elasticsearch-running.png 1080w,\n/static/207f7ba00a136cecf490655820d2c416/62a6a/elasticsearch-running.png 1122w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<hr>\n<h2 id=\"4-kibana-설치-및-실행\" style=\"position:relative;\"><a href=\"#4-kibana-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"4 kibana 설치 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Kibana 설치 및 실행</h2>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew <span class=\"token function\">install</span> elastic/tap/kibana-full</code></pre></div>\n<p><strong>kibana</strong> 또한 위 명령어로 <strong>kibana</strong>를 설치할 수 있고</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">kibana</code></pre></div>\n<p>설치 완료 후에는 <code class=\"language-text\">kibana</code> 명령어를 통해 실행할 수 있고,<br>\n다음과 같은 명령어로 백그라운드에서 실행할 수도 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew services start elastic/tap/kibana-full</code></pre></div>\n<p>실행 후에는 <a href=\"http://localhost:5601\">http://localhost:5601</a> 에 접속하여 제대로 실행되었는지 확인할 수 있다.<br>\n다음과 같은 화면이 보이면 성공<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAACv0lEQVQoz52S3WsUVxiH57J/gfTWRE0iUaQggopVK/W+IIXGm0JvtSJatVrwQktvFASpqAVv7EWRRCqKFZuo2ezOZklEY1a3Rnez2c1+ZOfbmZ2dOTPzlDnbm9564OGc874v78fvHGX3/gNs37Gb0a2fsXl0G0PDWxgYHJYMbhiR901Do/I8uHHzf4wwsKHP+sFhNg6NMjyylZ279qI8zGQYf/SYp0+myakFsrlZcrlZZrIq2VweNV/4nz2nzkr7TLZPVqKSmclJFADb7VKu1Gi1WqzUVnG9Hh+7lCCC7lqGD+rnmHNj2Pkv8RaPYl+ZxPzxTzo/P0ScucfEs+fsfJFl7HmefXMZjiy+5Lvflzh44w2HbpXY8+tr5qoOSpBA0PgDphTMV4cJ1XUkhRHMr39D/+om5dMTsP0Sv9z+C+XJON8UplH+nmAgM8knp+b59Pw8X1xdQPk2w6M3Rr/D0CniFk/gFM9iLxzHX76Of38B7doUjWuPCW/lyBcr/LBc4uTCPCf/ecXNWpXLz1ocu/ue78dL/PSgzFLbRQlCgYihrQvKKxaVukNPQI+EqtGm3GmgC68vkOvh1BsITYcohiTE1ZqYjRWIfUgSlFDEhKEgDHyCoCd3IUI8t4uhGViGhWXYdP0A3XbQTIs1w8IPQrqeh25YrOkWmmnTCyMUIWLcbo81zURLnR1DoukmabG0ERElBGHURySICBq2y1LbR/MiIhEThLH0K2mw63q0Vus063UqlSrL1Zr8PmlSw7QxTIcgEP1kvotpvePOahvlXIGL994CMV4QyQaUOE5oGi7TxTpqqUGt2aFj2FiOh2Y46KaDZbuyup+K3fOZrJbYv6gyNjXL8uULJI0KfoKUTkmFLDa7XJhscmWmTeeDwPEj3F6E3Y3ww3TsRI4USnkC6dNcH+IIu7KEaVjyYdOR/wV1gi4sXla38wAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"kibana-running.png\"\n        title=\"kibana-running.png\"\n        src=\"/static/f8f9f6b6c93265cc6ad7dc4971908600/37523/kibana-running.png\"\n        srcset=\"/static/f8f9f6b6c93265cc6ad7dc4971908600/e9ff0/kibana-running.png 180w,\n/static/f8f9f6b6c93265cc6ad7dc4971908600/f21e7/kibana-running.png 360w,\n/static/f8f9f6b6c93265cc6ad7dc4971908600/37523/kibana-running.png 720w,\n/static/f8f9f6b6c93265cc6ad7dc4971908600/302a4/kibana-running.png 1080w,\n/static/f8f9f6b6c93265cc6ad7dc4971908600/07a9c/kibana-running.png 1440w,\n/static/f8f9f6b6c93265cc6ad7dc4971908600/8da59/kibana-running.png 2742w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<hr>\n<h2 id=\"5-logstash-설치-및-실행\" style=\"position:relative;\"><a href=\"#5-logstash-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"5 logstash 설치 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. Logstash 설치 및 실행</h2>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew <span class=\"token function\">install</span> elastic/tap/logstash-full</code></pre></div>\n<p><strong>Logstash</strong>도 위 명령어를 통해 설치할 수 있고,<br>\n실행하기 전에 인덱싱하기 적절하게 필터링을 위한 설정 파일(<code class=\"language-text\">logstash-sample.conf</code>)을 수정하여 필터링 설정을 할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token builtin class-name\">cd</span> /opt/homebrew/etc/logstash</code></pre></div>\n<p><strong>Homebrew</strong>를 이용하여 설치한 경우에는 다음과 같은 경로에서 설정 파일들을 확인할 수 있고<br>\n여기서 <code class=\"language-text\">logstash-sample.conf</code> 설정 파일을 수정하면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">vi</span> logstash-sample.conf</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># Sample Logstash configuration for creating a simple</span>\n<span class=\"token comment\"># Beats -> Logstash -> Elasticsearch pipeline.</span>\ninput <span class=\"token punctuation\">{</span>\n  beats <span class=\"token punctuation\">{</span>\n    port <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">5044</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\noutput <span class=\"token punctuation\">{</span>\n  elasticsearch <span class=\"token punctuation\">{</span>\n    hosts <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"http://localhost:9200\"</span><span class=\"token punctuation\">]</span>\n    index <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}\"</span>\n    <span class=\"token comment\">#user => \"elastic\"</span>\n    <span class=\"token comment\">#password => \"changeme\"</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>설정 파일을 열어보면 위와 같이 파일이 구성되어 있는데 여기서 <code class=\"language-text\">filter</code>를 추가하여 필터링 설정을 할 수 있다.<br>\n(filter 설정에 대한 예시는 이후 포스트에서 다룰 예정)<br>\n이렇게 설정한 후에는 해당 디렉토리에서 다음 명령어를 통해 <strong>Logstash</strong>를 실행할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">logstash -f logstash-sample.conf</code></pre></div>\n<hr>\n<h2 id=\"6-filebeat-설치-및-실행\" style=\"position:relative;\"><a href=\"#6-filebeat-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"6 filebeat 설치 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. Filebeat 설치 및 실행</h2>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew <span class=\"token function\">install</span> elastic/tap/filebeat-full</code></pre></div>\n<p><strong>Filebeat</strong>도 위 명령어를 통해 설치할 수 있고,<br>\n실행하기 전에 설정 파일(<code class=\"language-text\">filebeat.yml</code>)을 수정하여 <strong>input</strong>과 <strong>output</strong>에 대한 설정을 할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token builtin class-name\">cd</span> /opt/homebrew/etc/filebeat\n<span class=\"token function\">vi</span> filebeat.yml</code></pre></div>\n<p><strong>Filebeat</strong> 설정에 대한 설명도 이후 포스트에서 예시를 통해 다룰 예정이다.<br>\n이렇게 설정한 후에는 해당 디렉토리에서 다음 명령어를 통해 <strong>Filebeat</strong>를 실행할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">filebeat -e                 <span class=\"token comment\"># 일반적으로 실행 하는 경우</span>\nfilebeat -e -c filebeat.yml <span class=\"token comment\"># -c 옵션은 configuration 파일을 특정할 때 사용 (-c 사용안하면 default는 filebeat.yml)</span></code></pre></div>\n<div class=\"table-of-contents\">\n<ul>\n<li><a href=\"#1-homebrew-%EC%84%A4%EC%B9%98\">1. Homebrew 설치</a></li>\n<li><a href=\"#2-elastic-tap-%EC%A0%80%EC%9E%A5%EC%86%8C-%EC%B6%94%EA%B0%80\">2. elastic tap 저장소 추가</a></li>\n<li><a href=\"#3-elasticsearch-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\">3. Elasticsearch 설치 및 실행</a></li>\n<li><a href=\"#4-kibana-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\">4. Kibana 설치 및 실행</a></li>\n<li><a href=\"#5-logstash-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\">5. Logstash 설치 및 실행</a></li>\n<li><a href=\"#6-filebeat-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89\">6. Filebeat 설치 및 실행</a></li>\n</ul>\n</div>","frontmatter":{"date":"April 06, 2022","title":"[Elastic] Elastic Stack(ELK Stack) - Mac OS 설치 방법","categories":"Database","author":"JFe","emoji":"🍺"},"fields":{"slug":"/elastic-mac-install/"}},"prev":{"id":"b7c11137-f10f-5c41-874c-9f3bba8eaaf0","html":"<h2 id=\"문제\" style=\"position:relative;\"><a href=\"#%EB%AC%B8%EC%A0%9C\" aria-label=\"문제 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>문제</h2>\n<p><a href=\"https://programmers.co.kr/learn/courses/30/lessons/42861\">https://programmers.co.kr/learn/courses/30/lessons/42861</a></p>\n<p>n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.</p>\n<p>다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.</p>\n<hr>\n<h2 id=\"제한사항\" style=\"position:relative;\"><a href=\"#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD\" aria-label=\"제한사항 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>제한사항</h2>\n<ul>\n<li>섬의 개수 n은 1 이상 100 이하입니다.</li>\n<li>costs의 길이는 <code class=\"language-text\">((n-1) * n) / 2</code> 이하입니다.</li>\n<li>임의의 i에 대해, costs[i][0] 와 costs[i][1]에는 다리가 연결되는 두 섬의 번호가 들어있고, costs[i][2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다.</li>\n<li>같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다.</li>\n<li>모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.</li>\n<li>연결할 수 없는 섬은 주어지지 않습니다.</li>\n</ul>\n<hr>\n<h2 id=\"입출력-예\" style=\"position:relative;\"><a href=\"#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88\" aria-label=\"입출력 예 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>입출력 예</h2>\n<table>\n<thead>\n<tr>\n<th>n</th>\n<th>costs</th>\n<th>return</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>[[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]]</td>\n<td>4</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2 id=\"-algorithm\" style=\"position:relative;\"><a href=\"#-algorithm\" aria-label=\" algorithm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🔍 Algorithm</h2>\n<p><strong>Kruskal</strong></p>\n<h2 id=\"-logic\" style=\"position:relative;\"><a href=\"#-logic\" aria-label=\" logic permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>💻 Logic</h2>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">find_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> x<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">!=</span> x<span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span>\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">union_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        a <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span>\n        b <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>a <span class=\"token operator\">&lt;</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>b<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> a\n        <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>a<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> b\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">kruskal</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        result <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n        <span class=\"token keyword\">while</span> h<span class=\"token punctuation\">:</span>\n            l<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> heapq<span class=\"token punctuation\">.</span>heappop<span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">if</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                union_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n                result <span class=\"token operator\">+=</span> l\n        <span class=\"token keyword\">return</span> result</code></pre></div>\n<ul>\n<li><strong>Kruskal 알고리즘 이용해서 MST 확인하는 함수</strong><br>\n우선순위 큐를 이용해서 MST 확인\n모든 노드 방문했는지 확인</li>\n</ul>\n<hr>\n<h2 id=\"-code\" style=\"position:relative;\"><a href=\"#-code\" aria-label=\" code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🧩 Code</h2>\n<details><summary>전체 코드 확인</summary>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> heapq\n<span class=\"token keyword\">def</span> <span class=\"token function\">solution</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">,</span> costs<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">def</span> <span class=\"token function\">find_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> x<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">!=</span> x<span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span>\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">union_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        a <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span>\n        b <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>a <span class=\"token operator\">&lt;</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>b<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> a\n        <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>a<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> b\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">kruskal</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        result <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n        <span class=\"token keyword\">while</span> h<span class=\"token punctuation\">:</span>\n            l<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> heapq<span class=\"token punctuation\">.</span>heappop<span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">if</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                union_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n                result <span class=\"token operator\">+=</span> l\n        <span class=\"token keyword\">return</span> result\n    \n    answer<span class=\"token punctuation\">,</span> h <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>\n    parent <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> x <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span>costs<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        heapq<span class=\"token punctuation\">.</span>heappush<span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>costs<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>costs<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> costs<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    answer <span class=\"token operator\">=</span> kruskal<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> answer</code></pre></div>\n</details>\n<hr>\n<h2 id=\"-review\" style=\"position:relative;\"><a href=\"#-review\" aria-label=\" review permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>📝 Review</h2>\n<p>Minimun Spanning Tree를 만들어야 된다고 생각해서 Kruskal 알고리즘을 떠올렸다.<br>\n얼마 전에 Kruskal 알고리즘으로 문제를 풀었어서 바로 생각해내서 풀 수 있었다.</p>\n<div class=\"table-of-contents\">\n<ul>\n<li><a href=\"#%EB%AC%B8%EC%A0%9C\">문제</a></li>\n<li><a href=\"#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD\">제한사항</a></li>\n<li><a href=\"#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88\">입출력 예</a></li>\n<li><a href=\"#-algorithm\">🔍 Algorithm</a></li>\n<li><a href=\"#-logic\">💻 Logic</a></li>\n<li><a href=\"#-code\">🧩 Code</a></li>\n<li><a href=\"#-review\">📝 Review</a></li>\n</ul>\n</div>","frontmatter":{"date":"April 12, 2022","title":"[Programmers] 42861번: 섬 연결하기 (Python)","categories":"Algorithm","author":"JFe","emoji":"💻"},"fields":{"slug":"/pg-42861/"}},"site":{"siteMetadata":{"siteUrl":"https://jfelog.netlify.app","comments":{"utterances":{"repo":"Go-Jaecheol/Jfe_Blog"}}}}},"pageContext":{"slug":"/elastic-open-data-api/","nextSlug":"/elastic-mac-install/","prevSlug":"/pg-42861/"}},
    "staticQueryHashes": ["1073350324","1956554647","2938748437"]}