[Splunk] Splunk Python 커스텀 엔드포인트 생성 및 GET 요청 보내기
[Splunk] Splunk Python 커스텀 엔드포인트 생성 및 GET 요청 보내기
커스텀 엔드포인트를 생성하기 위해서는 우선 Splunk Web 에 App 이 생성되어 있어야 한다.
[Splunk] Splunk App 추가하기
[Splunk] Splunk App 추가하기 Splunk Web에서 App 추가하기localhost:8000 접속 후 왼쪽 상단의 [관리] 클릭 현재 생성되어 있는 앱의 목록을 확인할 수 있다.앱의 경로는 윈도우 기준 `C:\Program Files\Splunk\etc\app
ramincoding.tistory.com
App의 구성은 다음과 같다.
App_Name
├─ bin
├─ default
├─ local
└─ metadata
엔드포인트를 설정해주는 설정 파일은 default 디렉토리에, 엔드포인트에서 일어나는 작업들은 bin 디렉토리에 작성해주면 된다.
우선 bin 디렉토리에 파이썬 핸들러(Python handler)를 작성해줘야 한다.
handler 작성
- path : `my_app/bin/custom_endpoint.py`
핸들러 안에 정의된 클래스는 PersistentServerConnectionApplication 을 상속받아 GET, POST 등을 구현할 수 있다.
이 파일은 bin 폴더 안에 정의되어 있어야 한다.
# splunk-app-examples/custom_endpoints/hello-world 예제 파일
from splunk.persistconn.application import PersistentServerConnectionApplication
class HelloWorld(PersistentServerConnectionApplication):
def __init__(self, _command_line, _command_arg):
super(PersistentServerConnectionApplication, self).__init__()
def handle(self, in_string):
payload = {
"text": "Hello world!"
}
return {'payload': payload, 'status': 200}
PersistentServerConnectionApplication 클래스
Splunk 에서 엔드포인트를 만들 때 제공하는 기본 추상 클래스이다.
Splunk 가 HTTP 요청을 이 클래스를 상속한 객체로 전달한다.
from splunk.persistconn.application import PersistentServerConnectionApplication
class HelloWorld(PersistentServerConnectionApplication):
이 클래스는 REST 엔드포인트의 핸들러 역할을 한다.
핸들러 역할을 한다는 것은 엔드포인트로 HTTP 요청이 들어오면, 그 요청을 받아서 처리하고 응답을 만드는 역할을 한다는 것이다.
이렇게 HTTP 요청이 들어오면 Splunk 에서는 클래스 내부의 handle 함수를 호출하게 된다.
def handle(self, in_string):
`is_string` 에는 요청 파라미터로 들어온 JSON 혹은 쿼리 문자열 데이터가 들어있다.
만약 사용자가 객체 형태의 요청 데이터를 보냈다면, 이 데이터가 객체의 형태로 들어가게 된다.
curl -X POST https://localhost:8089/services/custom/hello -d '{"name": "raminocoding"}' -u admin:password -k
handle 내부가 아래의 코드처럼 정의되어 있다고 가정한다면 출력되는 결과는 다음과 같다.
def handle(self, in_string):
print(in_string)
반환값 :
{
"headers": {
"content-type": "application/json",
"user-agent": "curl/8.0"
},
"query": {},
"path": "/services/custom/hello",
"method": "POST",
"payload": {
"name": "raminocoding"
}
}
이렇게 요청으로 들어온 객체를 핸들러 내부에서 받아와 사용할 경우 파이썬의 내장 모듈인 `json` 을 이용해 문자열을 json 으로 변환하면 된다.
import json
class HelloWorld(PersistentServerConnectionApplication):
def handle(self, in_string):
req = json.loads(in_string)
name = req.get('payload', {}).get('name', 'anonymous')
print(name);
`get()` 은 파이썬의 딕셔너리 자료형에 정의된 메서드이다. get() 을 사용하는 이유는 KeyError 를 방지하기 위함이다.
기본 문법은 ` dict.get(key, default) ` 로 key 값을 찾고 key 가 없을 경우 default 값을 대신 반환한다.
키값이 없을 경우 None 이 반환된다.
엔드포인트 설정
- path : `my_app/default/restmap.conf`
Python 핸들러를 Splunk 가 인식하게 하기 위해서는 restmap.conf 파일이 필요하다.
[script:hello-world]
match = /say-hello
script = hello_world.py
scripttype = persist
handler = application.HelloWorld
- [script:<이름>] : 엔드포인트 구분용 식별자
- match : 엔드포인트 URL
- script : 핸들러 파일 명
- scripttype : 런타임 환경 방식 설정. `persist` 는 Splunk 가 해당 스크립트를 메모리에 유지하며 요청을 처리한다. Python 은 파이썬 프로세스를 메모리에 유지하지 않고 매번 새로 실행하며 속도가 느리기 때문에 거의 사용하지 않는다.
- handler : <모듈명>.<클래스명>
App 재시작
splunk 실행파일이 있는 위치로 가서 명령어로 재시작해준다.
splunk restart
우분투/Mac 환경일 경우 :
.\splunk.exe restart
[참고] 로컬에서 매번 재시작하지 않고 바로 반영하는 방법
import datetime
print(datetime.datetime.now())
→ 코드가 실행되는 순간의 시간을 실시간으로 출력하는 코드로 로컬에서만 사용해야한다.
실제 운영 서버에서 실행하면 로그가 굉장히 많이 쌓이므로 서버에 부담이 될 수 있고, 앱이 작동하지 않을 수 있다.
따라서 운영 서버에서는 어쩔 수 없이 명령어로 서버를 재시작해줘야 한다.
실제 운영 서버에 아무생각 없이 `Git pull` 을 받아서 코드를 적용했는데, 엔드포인트로 요청이 보내지지 않는다면? 위의 코드를 점검해볼 필요가 있다.
Postman 요청하기
GET - 데이터 조회
Authorization 에 Splunk Web 의 계정 정보를 입력하고 `Get` 으로 요청을 보내면 Python handler 에서 작성해준 payload 값이 반환된다.
요청할 파라미터 값이 있는 경우 Params 에 key-value 를 입력해주면 된다.
그럴 경우 아래와 같이 URL 이 쿼리스트링 형태로 표현된다.
쿼리 스트링에 민감한 정보가 담기거나 너무 긴 경우 get 요청은 적절하지 않을 수 있다.