시작하기
기본 개념
파일 전송 정보를 모니터링 환경과 연결하기
파일 전송 작업이 실행되면 작업 상태, 처리된 파일 수와 용량, 실행 시간, 전송 성능 등 다양한 운영 정보가 생성됩니다.
Datadog·Grafana 연동은 이러한 정보를 모니터링 환경으로 수집해 파일 전송 작업을 전체 시스템 운영 정보와 함께 관리할 수 있도록 구성합니다.
File Transfer
│
│ Status · Metrics · Events
▼
Monitoring Environment
│
┌────┴────┐
▼ ▼
Datadog Grafana
│
▼
Operations

파일 전송 환경을 모니터링 시스템과 연결하면 개별 파일 작업의 실행 결과와 전체 운영 상태를 같은 기준으로 확인할 수 있습니다.
모니터링 흐름
전송 실행부터 정보 수집과 운영 확인까지 이어가기
파일 전송이 실행되면 작업 과정에서 상태와 성능 정보가 생성됩니다. 생성된 정보는 모니터링 환경으로 수집되고, 대시보드와 이벤트 기준에 따라 운영 확인에 활용됩니다.
파일 전송 실행
│
▼
상태 · 성능 정보 생성
│
▼
모니터링 정보 수집
│
┌────┴───────┐
▼ ▼
대시보드 이벤트 감지
▼ ▼
운영 확인 운영 알림

이 흐름을 통해 파일 전송의 현재 상태와 주요 운영 이벤트를 기존 모니터링 환경에서 확인할 수 있습니다.
운영 변화
기존 운영 화면에서 파일 전송 정보 함께 관리하기
Datadog·Grafana와 연결하면 파일 전송 정보가 기존 운영 환경의 다른 시스템 정보와 함께 관리됩니다.
| 구분 | 파일 전송 중심 확인 | 모니터링 환경 통합 |
|---|---|---|
| 상태 | 작업별 실행 결과 확인 | 전체 운영 화면에서 상태 확인 |
| 성능 | 개별 실행 결과 기준 확인 | 시간과 장비별 성능 변화 확인 |
| 이벤트 | 작업별 상태 확인 | 운영 기준에 따른 이벤트 감지 |
| 분석 | 개별 작업 중심 확인 | 누적 데이터 기반 운영 분석 |
이렇게 파일 전송 정보를 기존 모니터링 환경과 연결하면 현재 상태 확인부터 장기적인 운영 분석까지 하나의 흐름으로 이어갈 수 있습니다.
IT 엔지니어
파일 전송 정보를 기존 모니터링 환경으로 통합하기
모니터링 연결
파일 전송 환경과 모니터링 도구 연결하기
먼저 이노릭스에서 생성되는 파일 전송 정보를 Datadog 또는 Grafana에서 활용할 수 있도록 연동 환경을 구성합니다.
파일 전송 장비와 모니터링 시스템의 연결 정보를 설정한 후 수집할 정보와 적용 범위를 지정합니다.
┌────────────────┐
│ File Transfer │
│ Environment │
└────────┬───────┘
│
▼
┌────────────────┐
│ Monitoring │
│ Integration │
└────────┬───────┘
│
┌────┴────┐
▼ ▼
Datadog Grafana

연동 환경이 준비되면 파일 전송 작업에서 생성되는 운영 정보를 지정된 모니터링 시스템으로 수집할 수 있습니다.
정보 수집
전송 상태와 성능 정보를 수집하기
연동이 완료되면 운영에 필요한 파일 전송 정보를 수집 대상으로 설정합니다.
실행 상태와 파일 처리 정보, 처리 시간과 전송 성능을 기준으로 필요한 데이터를 모니터링 환경에 연결할 수 있습니다.
File Transfer Run
│
├── Status
│
├── Files
│
├── Duration
│
├── Transfer Rate
│
└── Events
│
▼
Monitoring Data
| 구분 | 주요 수집 정보 |
|---|---|
| 실행 | 작업 상태와 실행 결과 |
| 파일 | 처리된 파일 수와 용량 |
| 시간 | 시작 시간과 처리 기간 |
| 성능 | 전송 속도와 처리량 |
| 이벤트 | 시작, 완료, 상태 변경 |
| 장비 | 작업을 실행한 시스템 |
수집한 정보는 대시보드 표시와 이벤트 감지, 운영 분석의 기준으로 활용할 수 있습니다.
대시보드
주요 파일 전송 정보를 운영 화면에서 확인하기
수집된 파일 전송 정보를 Datadog 또는 Grafana의 대시보드에 구성합니다.
운영 목적에 따라 현재 실행 중인 작업과 최근 처리 결과, 장비별 처리량과 성능 변화를 하나의 화면에 표시할 수 있습니다.
┌──────────────────────────────────────┐
│ Operations Dashboard │
├──────────────┬────────────┬──────────┤
│ Running │ Completed │ Transfer │
│ Transfers │ Transfers │ Volume │
├──────────────┼────────────┼──────────┤
│ Device │ Duration │ Rate │
│ Status │ Trend │ Trend │
└──────────────┴────────────┴──────────┘

대시보드에는 다음과 같은 정보를 구성할 수 있습니다.
현재 실행 중인 파일 전송
최근 완료된 작업
장비별 처리량
시간대별 전송량
평균 실행 시간
전송 속도 변화
주요 상태 이벤트
이를 통해 파일 전송 환경의 현재 운영 상태를 다른 시스템 정보와 함께 확인할 수 있습니다.
알림 설정
주요 상태 변화와 복구 이벤트에 따라 알림 보내기
운영자가 확인해야 하는 파일 전송 상태와 성능 변화를 이벤트 조건으로 설정합니다.
설정한 조건이 발생하면 운영 환경에서 사용하는 알림 흐름과 연결할 수 있으며, 작업 상태가 변경된 이후의 복구 이벤트도 함께 관리할 수 있습니다.
Monitoring Data
│
▼
Alert Rule
│
┌─────┴─────┐
▼ ▼
Event Recovery
Detected Detected
▼ ▼
Alert Recovery

| 이벤트 기준 | 활용 |
|---|---|
| 실행 상태 | 주요 상태 변경 확인 |
| 실행 시간 | 처리 시간 변화 확인 |
| 전송 성능 | 성능 기준 변화 확인 |
| 장비 상태 | 장비별 실행 상태 확인 |
| 복구 상태 | 정상 상태로 전환된 이벤트 확인 |
알림 기준을 구성하면 운영자가 확인할 파일 전송 이벤트를 기존 모니터링 체계에 연결할 수 있습니다.
복구 추적
문제 발생부터 재실행과 복구 결과까지 확인하기
확인이 필요한 이벤트가 발생하면 해당 시점의 모니터링 정보와 파일 전송 실행 기록을 함께 확인합니다.
이벤트 발생 시점의 장비 상태와 성능 정보, 실제 실행된 파일 전송 작업을 확인한 후 필요한 조치를 진행하고 재실행 결과를 추적합니다.
Event
│
▼
Run Details
│
▼
Environment Check
│
▼
Action
│
▼
Retry
│
▼
New Run
│
▼
Recovery

이 흐름을 통해 하나의 이벤트가 발생한 시점부터 조치와 재실행, 이후의 복구 상태까지 연결해 확인할 수 있습니다.
운영 분석
누적된 전송 정보를 기준으로 장비와 작업 흐름 분석하기
일정 기간 동안 누적된 실행 정보는 파일 전송 환경의 장기적인 운영 흐름을 분석하는 데 활용할 수 있습니다.
장비와 Flow, 시간 기준으로 데이터를 구분하면 처리량과 실행 시간, 전송 성능의 변화를 비교할 수 있습니다.
Transfer Data
│
┌────────────┼────────────┐
▼ ▼ ▼
Device Flow Time
│ │ │
└────────────┼────────────┘
▼
Operations
Analysis
│
┌────────────┼────────────┐
▼ ▼ ▼
Volume Duration Performance

| 분석 기준 | 확인 내용 |
|---|---|
| 장비별 | 장비별 처리량과 실행 상태 |
| Flow별 | 작업별 실행 횟수와 처리 흐름 |
| 기간별 | 시간과 기간에 따른 전송량 변화 |
| 성능별 | 처리 시간과 전송 속도 변화 |
| 이벤트별 | 주요 운영 이벤트 발생 추이 |
개발자
전송 상태와 이력을 조회해 모니터링 도구가 읽는 지표로 내보내기
연동 준비
공통 호출 코드와 커서 순회 준비하기
import os
import requests
BASE_URL = os.getenv("INNORIX_BASE_URL", "https://app.innorix.com").rstrip("/")
TOKEN = os.environ["INNORIX_ACCESS_TOKEN"]
WORKSPACE_ID = os.getenv("INNORIX_WORKSPACE_ID") # optional; falls back to the current workspace
STATUS_COMPLETE = 2
TERMINAL = {2, 4, 5, 9, 99} # complete / error / cancelled / partial / failed
NOT_SUCCEEDED = {4, 5, 9, 99}
def api(method, path, body=None, params=None):
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {TOKEN}",
}
if WORKSPACE_ID:
headers["x-workspace-id"] = WORKSPACE_ID
response = requests.request(
method, BASE_URL + path,
headers=headers, json=body, params=params, timeout=30,
)
payload = response.json() if response.content else {}
if not response.ok:
raise RuntimeError(payload.get("message") or f"HTTP {response.status_code}")
return payload.get("data")
def is_terminal(detail):
return detail.get("isTerminal", detail.get("status") in TERMINAL)목록 조회는 커서 페이징입니다. 순회 코드를 하나 만들어 여러 엔드포인트에 재사용합니다.
def paginate(path, params=None, limit=200, max_pages=50):
query = dict(params or {})
query["limit"] = limit
cursor = None
for _ in range(max_pages):
if cursor:
query["cursor"] = cursor
result = api("GET", path, params=query) or {}
for record in result.get("data") or []:
yield record
pagination = result.get("pagination") or {}
if not pagination.get("hasMore"):
return
cursor = pagination.get("nextCursor")
if not cursor:
return전송 목록과 이력은 data.data 배열로, 페이징 정보는 data.pagination으로 반환됩니다. 페이지 상한을 두면 수집 스크립트가 예상보다 많은 이력을 만나 오래 실행되는 것을 막을 수 있습니다.
수집 대상 정하기
어떤 정보를 어디서 얻을지 정리하기
| 지표 | 얻는 곳 | 형태 |
|---|---|---|
| 진행 중 전송 건수와 진행률 | /api/transfers | 커서 페이징 |
| 완료 전송 건수와 실패율 | /api/transfer-history | 커서 페이징 |
| 장비별 실패율 | /api/devices/{deviceId}/transfer-history | 커서 페이징 |
| 자동화별 회차 결과 | /api/automations/{automationId}/executions | 배열 |
| 장비 연결 상태 | /api/devices + /connectivity | 장비 수만큼 호출 |
지표는 적은 수로 시작합니다. 아래 네 가지로 대부분의 운영 질문에 답할 수 있습니다.
| 지표 이름 | 형태 | 답하는 질문 |
|---|---|---|
transfer.active | 게이지 | 지금 몇 건이 돌고 있는가 |
transfer.completed · failed | 카운터 | 오늘 얼마나 성공했고 실패했는가 |
transfer.failure_rate | 게이지 | 실패가 늘고 있는가 |
device.connected | 게이지 | 장비가 붙어 있는가 |
진행 중 상태는 짧게, 이력 집계는 길게 잡습니다. 요청이 과도하면 429가 반환되므로 장비가 많은 환경에서는 연결 상태 조회 주기를 늘립니다.
상태 조회
진행 중인 전송과 장비 상태 가져오기
def poll_active(automation_id=None):
params = {"automationId": automation_id} if automation_id else None
return list(paginate("/api/transfers", params=params, limit=50))
# list items expose id/progress; totalSize·fileCount live under detail
for record in poll_active():
print(record["id"], record["statusName"], record.get("progress", 0),
record["sourceDeviceName"], record["targetDeviceName"])전송을 식별하는 monitorId를 애플리케이션이 미리 보관할 필요는 없습니다. 관리 화면이나 다른 경로로 만들어진 전송도 이 목록에 함께 조회됩니다.
장비 연결 상태는 장비 수만큼 호출이 필요합니다.
def poll_devices():
result = api("GET", "/api/devices", params={"page": 1, "size": 200}) or {}
for device in result.get("devices") or []:
state = api("GET", f"/api/devices/{device['deviceId']}/connectivity") or {}
yield device["deviceId"], device["name"], bool(state.get("isConnected"))응답의 연결 여부는 isConnected입니다. 함께 오는 stateLabel은 화면에 그대로 쓸 수 있습니다.
수백 대 규모라면 조회 주기를 길게 잡고, 연결이 끊긴 장비만 짧은 주기로 다시 확인합니다.
이력 집계
완료된 전송을 집계해 실패율 내기
from collections import Counter
from datetime import datetime, timedelta, timezone
def window(days):
end = datetime.now(timezone.utc)
fmt = "%Y-%m-%dT%H:%M:%SZ"
return (end - timedelta(days=days)).strftime(fmt), end.strftime(fmt)
def history(days=1, device_id=None):
start, end = window(days)
params = {"startDate": start, "endDate": end}
path = (f"/api/devices/{device_id}/transfer-history" if device_id
else "/api/transfer-history")
return list(paginate(path, params=params, limit=200))
def summarize(rows):
counts = Counter(row.get("status") for row in rows)
total = sum(counts.values())
failed = sum(counts.get(code, 0) for code in NOT_SUCCEEDED)
return {
"total": total,
"completed": counts.get(STATUS_COMPLETE, 0),
"failed": failed,
"failure_rate": failed / total if total else 0.0,
}부분 완료(9)와 취소(5)도 종료 상태입니다. 성공만 세면 실패가 성공으로 잡히므로 성공 값은 완료(2) 하나로 둡니다.
장비 단위 실패율은 장비별 이력 조회로 냅니다. 전체 이력을 받아 클라이언트에서 나누는 것보다 전송량이 적습니다. 전송 건수가 적은 장비는 실패 한 건으로도 실패율이 크게 튀므로, 지표로 낼 때는 건수도 함께 내보냅니다.
이력 파일 내보내기
감사와 보고용으로 전체 이력 받기
CSV 내보내기는 JSON이 아니라 텍스트로 응답합니다. JSON 파서를 거치지 않고 원본 응답으로 받습니다.
def export_csv(days, out_path):
params = {
"periodDays": days,
"page": 1,
"size": 10000,
"filter": "[]", # the server parses this as a JSON string, so send an empty array
"sort": "startDate:desc",
}
response = requests.get(
BASE_URL + "/api/transfer-history/export",
headers={"Authorization": f"Bearer {TOKEN}"},
params=params, timeout=120,
)
if not response.ok:
raise RuntimeError(response.text[:200])
with open(out_path, "w", encoding="utf-8-sig") as handle:
handle.write(response.text)조건이 없어도 filter에 빈 배열 문자열("[]")을 넣어 보냅니다. 서버가 이 값을 JSON으로 파싱하기 때문입니다.
sort에 넣을 수 있는 필드는 정해져 있습니다.
| 허용 필드 |
|---|
status · sourceDeviceName · targetDeviceName · totalSize |
sourceFileCount · startDate · endDate · automationName |
formattedTransferTime · savedTime |
createdAt 같은 목록에 없는 필드를 넣으면 거부됩니다.
지표 변환과 전송
수집한 값을 모니터링 도구 형식으로 바꿔 보내기
라벨은 조합 수가 그대로 시계열 수가 됩니다.
| 라벨 | 넣어도 되는가 |
|---|---|
| 소스 장비, 대상 장비 | 예 |
| 자동화 이름 | 예 |
| 작업 공간 | 예 |
monitorId | 아니오 |
| 파일 경로, 파일명 | 아니오 |
전송 단위 정보가 필요하면 지표가 아니라 로그나 이벤트로 보냅니다.
import time
def build_metrics(active_count, summary, devices):
now = int(time.time())
points = [
{"metric": "innorix.transfer.active", "value": active_count, "tags": []},
{"metric": "innorix.transfer.completed",
"value": summary["completed"], "tags": []},
{"metric": "innorix.transfer.failed",
"value": summary["failed"], "tags": []},
{"metric": "innorix.transfer.failure_rate",
"value": round(summary["failure_rate"], 4), "tags": []},
]
for device_id, name, connected in devices:
points.append({
"metric": "innorix.device.connected",
"value": 1 if connected else 0,
"tags": [f"device:{name}"],
})
return [{**p, "timestamp": now} for p in points]지표 수집이 지연되거나 실패해도 전송 처리에 영향을 주어서는 안 됩니다. 수집 스크립트는 전송 경로와 분리된 별도 프로세스로 실행합니다.
알림 연동 등록
모니터링 도구와 협업 도구를 연동 항목으로 등록하기
유형마다 필요한 설정이 다르므로 값을 추측하지 말고 규칙을 먼저 조회합니다.
rules = api("GET", "/api/integrations/rules",
params={"category": "monitoring"}) or {}
for name, rule in rules.items():
print(name, rule.get("category"), rule.get("modes"))
for field in rule.get("fields") or []:
mark = "required" if field.get("required") else "optional"
print(" ", field["id"], field["label"], field["type"], mark)한 유형만 조회할 때는 응답이 유형 이름으로 한 번 더 중첩되어 반환됩니다.
data = api("GET", "/api/integrations/rules/slack") or {}
rule = data.get("slack") or next(iter(data.values()), {})규칙 응답의 fields가 곧 등록 요청의 config에 넣을 키 목록입니다.
VALID_EVENTS = ["started", "completed", "paused", "resumed",
"recovered", "canceled", "error", "skipped"]
api("POST", "/api/integrations", {
"name": "transfer alerts",
"type": "slack",
"mode": "webhook",
"webhookUrl": WEBHOOK_URL,
"config": {
"name": "transfer alerts",
"webhookUrl": WEBHOOK_URL,
"channel": "#file-ops",
},
# toggle per event; this is what wires transfer events to the integration
"notificationConfig": {"events": {"completed": True, "error": True}},
})notificationConfig.events는 이벤트 이름을 키로 두고 참·거짓으로 지정합니다. 등록해 두면 같은 작업 공간의 전송이 자동으로 알림 대상이 됩니다.
| 확인 항목 | 확인 내용 |
|---|---|
| 수집 대상 | 내보낼 지표 항목 |
| 조회 범위 | 기간과 상태 필터 |
| CSV 내보내기 | filter와 sort 허용 필드 |
| 라벨 | 시계열 수를 좌우하는 조합 |
| 연동 | 등록된 도구와 알림 이벤트 |