Monitoring

참고

네이버 클라우드 플랫폼의 상품 사용 방법을 보다 상세하게 제공하고, 다양한 API의 활용을 돕기 위해 [설명서][API 참조서]를 구분하여 제공하고 있습니다.

Monitoring API 참조서 바로가기 >>
Monitoring 설명서 바로가기 >>

개요

API는 RESTful API 방식의 HTTP GET/POST 메소드 호출로 실행하며 API를 사용해 원하는 형태의 모니터링 관리 기능을 만들 수 있습니다.

공통설정

API URL

https://ncloud.apigw.ntruss.com/monitoring/v1

요청 헤더

Header Description
x-ncp-apigw-timestamp 1970년 1월 1일 00:00:00 협정 세계시(UTC)부터의 경과 시간을 밀리초(Millisecond)로 나타낸 것이다.
API Gateway 서버와 시간차가 5분 이상 나는 경우 유효하지 않은 요청으로 간주
x-ncp-apigw-api-key API Gateway에서 발급받은 키
x-ncp-iam-access-key 네이버 클라우드 플랫폼에서 발급받은 API Key 또는 IAM에서 발급받은 AccessKey
x-ncp-apigw-signature-v1 위 예제의 Body를 AccessKey와 맵핑되는 SecretKey로 암호화한 서명
HMAC 암호화 알고리즘은 HmacSHA256 사용

시나리오

생성/운영 중인 서버에 대한 모니터링 관련 정보를 조회할 수 있는 간단한 시나리오를 통해 모니터링 API에 대한 사용법을 익힐 수 있습니다.

설명

소유하고 있는 서버에 대한 모니터링 통계 정보를 조회해 봅니다.

  1. 서버별로 제공 가능한 Metric정보 조회

    • 서버별로 통계 정보가 제공 가능한 Metric 이 어떤 것이 있는지 조회해 봅니다.
  2. Metric에 대한 통계 정보 조회

    • 특정 기간에 대한 서버(들)의 Metric 통계 정보를 조회해 봅니다.

인증

해당 가이드에서는 시나리오 수행을 위한 인증 URL을 만드는 과정을 살펴 보도록 합니다.
Java 샘플코드로 작성되었고, GET 방식의 http request method를 사용하여 요청하는 방식으로 작성되었습니다.
실제 요청 시에는 GET 방식으로 요청하는 것보다 POST 방식으로 request body에 값을 넣어서 요청하는 것을 추천합니다.

인증 URL생성

인증키를 생성하기 위해서 아래와 같은 절차를 따릅니다.

Base String 생성

  1. 액션파라미터에 Base string 생성에 필요한 인증 파라미터를 추가
  2. 요청파라미터와 Value 값을 알파벳 순으로 정렬
  3. base string = RequestMethod + ‘&’ + oauthEncode(requestUrl) + ‘&’ + oauthEncode(queryString)

서명서 생성

Secret Key와 위에서 생성한 baseString을 가지고 HMAC SHA-1 해시알고리즘을 이용하여 서명서를 생성합니다.

요청 URL 생성

서명서까지 생성이 완료되었으면, 요청 URL을 생성하여 API를 요청합니다.
OAuth 외부 라이브러리를 이용하여, authorization 헤더에 authparams 포함하여 쉽게 요청할 수도 있습니다.

자세한 사항은 API 가이드 를 참고하기 바란다. * signpost-core 라이브러리: http://code.google.com/p/oauth-signpost/wiki/GettingStarted

요청 URL 생성 java sample code

아래는 요청 URL을 생성하는 Java sample code 이다.
해당 코드는 commons-codec-1.4.jar 라이브러리에 dependency를 가집니다. 따라서 아래 코드를 수행하기 위해서는 해당 jar가 자신의 build path에 추가 되어야 합니다.
해당 JAR는 간단하게 google.com 이나 naver.com에서 검색을 통해서 다운로드할 수 도 있고, 또는 네이버 클라우드 비즈 라이브러리에서 Dependency 항목으로 함께 제공됩니다.

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.net.URLCodec;

/**
 * @author admin
 */
public class OAuthMain {
	private static String consumerKey = "CCe2T0ilv4aO3kIevT3x";
	private static String consumerSecret = "UXbllHzrAVV7rmcE270sESJZa3Fh8I2kOiBTf0oE";

	public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
		String requestMethod = "GET";
		String requestUrl = "https://api.ncloud.com";
		String monitoringNameSpace = "/monitoring/";

		Map<String, List<String>> requestParameters = new HashMap<String, List<String>>();

		requestParameters.put("action", Arrays.asList("getMetricStatistics"));
		requestParameters.put("instanceNoList.1", Arrays.asList("68745"));
		requestParameters.put("metricName", Arrays.asList("CPUUtilization"));
		requestParameters.put("startTime", Arrays.asList("2014-06-09T17:50:00+09:00"));
		requestParameters.put("endTime", Arrays.asList("2014-06-09T18:50:00+09:00"));
		requestParameters.put("period", Arrays.asList("1800"));
		requestParameters.put("responseFormatType", Arrays.asList("xml"));

		SortedMap<String, SortedSet<String>> significantParameters = getSignificateParametersForSiganturBaseString(requestParameters, consumerKey);
		String signatureBaseString = makeSignatureBaseString(requestMethod, requestUrl + monitoringNameSpace, significantParameters);
		String signature = sign(signatureBaseString, consumerSecret);
		String requestFullUrl = makeRequestUrl(requestUrl + monitoringNameSpace, significantParameters, signature);
		System.out.println(requestFullUrl);
	}

	/**
	 * signature base string을 만들기 위한 significateParameter 세팅
	 * @param requestParameters
	 * @param consumerKey
	 * @return
	 */
	private static SortedMap<String, SortedSet<String>> getSignificateParametersForSiganturBaseString(Map<String, List<String>> requestParameters, String consumerKey) {
		SortedMap<String, SortedSet<String>> significateParameters = convertTypeToSortedMap(requestParameters);

		SortedSet<String> consumerKeySet = new TreeSet<String>();
		consumerKeySet.add(consumerKey);
		significateParameters.put("oauth_consumer_key", consumerKeySet);

		SortedSet<String> nonceSet = new TreeSet<String>();
		nonceSet.add(generateNonce());
		significateParameters.put("oauth_nonce", nonceSet);

		SortedSet<String> signatureMethodSet = new TreeSet<String>();
		signatureMethodSet.add("HMAC-SHA1");
		significateParameters.put("oauth_signature_method", signatureMethodSet);

		SortedSet<String> timestampSet = new TreeSet<String>();
		timestampSet.add(generateTimestamp());
		significateParameters.put("oauth_timestamp", timestampSet);

		SortedSet<String> versionSet = new TreeSet<String>();
		versionSet.add("1.0");
		significateParameters.put("oauth_version", versionSet);

		return significateParameters;
	}

	/**
	 * @param requestParameters
	 * @param significateParameters
	 */
	private static SortedMap<String, SortedSet<String>> convertTypeToSortedMap(Map<String, List<String>> requestParameters) {
		SortedMap<String, SortedSet<String>> significateParameters = new TreeMap<String, SortedSet<String>>();
		Iterator<String> parameterNames = requestParameters.keySet().iterator();
		while (parameterNames.hasNext()) {
			String parameterName = (String)parameterNames.next();
			List<String> parameterValues = requestParameters.get(parameterName);
			if (parameterValues == null) {
				parameterValues = new ArrayList<String>();
			}

			for (String parameterValue : parameterValues) {
				if (parameterValue == null) {
					parameterValue = "";
				}

				SortedSet<String> significantValues = significateParameters.get(parameterName);
				if (significantValues == null) {
					significantValues = new TreeSet<String>();
					significateParameters.put(parameterName, significantValues);
				}
				significantValues.add(parameterValue);
			}

		}
		return significateParameters;
	}

	/**
	 * @param url
	 * @return
	 */
	private static String normalizeUrl(String url) {
		try {
			URL requestURL = new URL(url);
			StringBuilder normalized = new StringBuilder(requestURL.getProtocol().toLowerCase()).append("://").append(requestURL.getHost().toLowerCase());
			if ((requestURL.getPort() >= 0) && (requestURL.getPort() != requestURL.getDefaultPort())) {
				normalized.append(":").append(requestURL.getPort());
			}
			normalized.append(requestURL.getPath());
			return normalized.toString();
		} catch (MalformedURLException e) {
			throw new IllegalStateException("Illegal URL for calculating the OAuth signature.", e);
		}
	}

	private static String generateTimestamp() {
		return Long.toString(System.currentTimeMillis() / 1000L);
	}

	private static String generateNonce() {
		return Long.toString((new Random()).nextLong());
	}

	/**
	 * base string 생성
	 * @param requestMethod
	 * @param requestUrl
	 * @param significantParameters
	 * @return
	 */
	private static String makeSignatureBaseString(String requestMethod, String requestUrl, SortedMap<String, SortedSet<String>> significantParameters) {
		StringBuilder queryString = getRequestQueryString(significantParameters);

		requestUrl = normalizeUrl(requestUrl);
		requestUrl = OAuthCodec2.oauthEncode(requestUrl);

		return new StringBuilder(requestMethod.toUpperCase()).append('&').append(requestUrl).append('&').append(OAuthCodec2.oauthEncode(queryString.toString())).toString();
	}

	/**
	 * query string 생성
	 * @param significantParameters
	 * @return
	 */
	private static StringBuilder getRequestQueryString(SortedMap<String, SortedSet<String>> significantParameters) {
		StringBuilder queryString = new StringBuilder();
		Iterator<Map.Entry<String, SortedSet<String>>> paramIt = significantParameters.entrySet().iterator();
		while (paramIt.hasNext()) {
			Map.Entry<String, SortedSet<String>> sortedParameter = paramIt.next();
			Iterator<String> valueIt = sortedParameter.getValue().iterator();
			while (valueIt.hasNext()) {
				String parameterValue = valueIt.next();
				queryString.append(OAuthCodec2.oauthEncode(sortedParameter.getKey())).append('=').append(OAuthCodec2.oauthEncode(parameterValue));
				if (paramIt.hasNext() || valueIt.hasNext()) {
					queryString.append('&');
				}
			}
		}
		return queryString;
	}

	/**
	 * base string과 consumer secret key를 가지고 signature 생성
	 * @param signatureBaseString
	 * @param consumerSecret
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws UnsupportedEncodingException
	 * @throws InvalidKeyException
	 */
	private static String sign(String signatureBaseString, String consumerSecret) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
		Mac mac = Mac.getInstance("HmacSHA1");
		SecretKeySpec spec = new SecretKeySpec(new String(consumerSecret + "&").getBytes("UTF-8"), "HmacSHA1");
		mac.init(spec);
		byte text[] = signatureBaseString.getBytes("UTF-8");
		byte signatureBytes[] = mac.doFinal(text);
		signatureBytes = Base64.encodeBase64(signatureBytes);
		String signature = new String(signatureBytes, "UTF-8");
		return signature;
	}

	/**
	 * request URL 생성
	 * @param requestParameters
	 * @param signature
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private static String makeRequestUrl(String requestUrl, SortedMap<String, SortedSet<String>> significantParameters, String signature) throws UnsupportedEncodingException {
		StringBuilder queryString = getRequestQueryString(significantParameters);
		queryString.append('&').append("oauth_signature").append("=").append(URLEncoder.encode(signature, "UTF-8"));
		return new StringBuffer(requestUrl).append("?").append(queryString.toString()).toString();
	}
}

class OAuthCodec2 extends URLCodec {

	private OAuthCodec2() {
	}

	public static String oauthEncode(String value) {
		if (value == null)
			return "";
		try {
			return new String(URLCodec.encodeUrl(SAFE_CHARACTERS, value.getBytes("UTF-8")), "US-ASCII");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	public static String oauthDecode(String value) throws DecoderException {
		if (value == null)
			return "";
		try {
			return new String(URLCodec.decodeUrl(value.getBytes("US-ASCII")), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	protected static final BitSet SAFE_CHARACTERS;

	static {
		SAFE_CHARACTERS = (BitSet)URLCodec.WWW_FORM_URL.clone();
		SAFE_CHARACTERS.clear(42);
		SAFE_CHARACTERS.clear(32);
		SAFE_CHARACTERS.set(126);
	}
}

Main 메소드를 수행하면, 인증URL이 포함된 아래와 같은 요청 URL을 볼 수 있습니다.

https://api.ncloud.com/monitoring/?action=getMetricStatistics&endTime=2014-06-09T18%3A50%3A00%2B09%3A00&instanceNoList.1=68745&instanceNoList.2=68417&metricName=CPUUtilization&oauth_consumer_key=CCe2T0ilv4aO3kIevT3x&oauth_nonce=8844649875013849059&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1402484811&oauth_version=1.0&period=60&responseFormatType=xml&startTime=2014-06-09T17%3A50%3A00%2B09%3A00&oauth_signature=DUxxYjHIAtSIxd%2BA7TLYP0Wt3f0%3D

사용자는 My Page > API 인증키 관리 화면에서 Access Key, Secret Key를 발급받고, 위의 예제에서 consumerKey, consumerSecret 값을 해당 값으로 변경 후 테스트 해야 합니다.

모니터링의 경우 namespace가 /monitoring/,으로 사용되니 참고 바라며, 해당 URL복사하여, 브라우저로 요청을 합니다.

시나리오 수행

모든 시나리오는 인증의 샘플코드 방식으로 설명되며, Main 메소드의 파라미터 부분에 대해서만 설명합니다.
자신이 소유하고 있는 서버의 Metric 통계 정보를 조회하기 위해서는 반드시 서버의 인스턴스 번호를 알아야 하며, 통계 정보로 제공 가능한 Metric이 어떤 것들이 있는지 알아야 합니다.

오퍼레이션


아쉬운 점이 있다면 이야기해 주세요.
0/5000
내용을 입력해 주세요
의견 보내기