클래식 인프라에 대한 시스템 이벤트 감사

클래식 인프라 계정이 있는 경우에는 감사 로그를 보고 스토리지 복제 이벤트를 모니터할 수 있습니다. 감사 로그는 로그인 시도, 포트 속도 업데이트, 전원 다시 시작 및 IBM Cloud 인프라 지원 직원이 수행하는 상호작용과 같은 각 사용자의 상호작용을 추적합니다.

콘솔에서 감사 로그 보기

감사 로그를 보려면 IBM Cloud® 콘솔에서 관리 > 계정으로 이동하여 감사 로그를 선택하십시오. 감사 로그에는 처음에 사용자가 계정에서 수행한 최근 25개의 상호작용이 표시됩니다. 언제든지 최대 200개의 상호작용을 볼 수 있습니다. 페이지당 항목 페이지 메뉴를 펼쳐서 자세한 결과를 볼 수 있습니다.

사용자의 액세스 로그 보기

감사 로그 페이지에서 특정 사용자가 시도한 각각의 액세스에 대한 데이터를 볼 수도 있습니다. 로그는 각 액세스 시도에 대한 날짜와 시간소인 및 IP 주소를 표시합니다. 사용자의 액세스 로그를 보려면 다음 단계를 수행하십시오.

  1. IBM Cloud 콘솔에서 관리 > 계정으로 이동하여 감사 로그를 선택하십시오.
  2. 그런 다음 사용자에 맞게 필터링하고 보려는 시간 범위를 선택한 후 오브젝트 유형을 선택하십시오.

각 사용자에 대한 액세스 로그에는 액세스가 시도된 IP 주소와 함께 날짜별로 해당 사용자가 수행한 액세스 시도를 표시합니다. 액세스 로그 내의 정보는 읽기 전용입니다.

감사 로그에 대한 액세스 권한 부여

감사 로그를 보려면 모든 계정 관리 서비스에서 뷰어 이상의 역할이 필요합니다. 클래식 인프라 권한의 경우 사용자에게 수퍼유저 역할이 지정되어야 합니다.

SoftLayer API를 사용하여 감사 로그 보기

SoftLayer API를 사용하여 감사 로그를 볼 수 있습니다. SoftLayer® Application Programming Interface는 개발자 및 시스템 관리자에게 IBM Cloud 백엔드 시스템과의 직접 상호작용을 제공하는 개발 인터페이스입니다. SoftLayer API는 IBM Cloud 콘솔에서 많은 기능을 제공합니다. 일반적으로, 상호작용이 IBM Cloud 콘솔에서 가능한 경우 API에서 실행될 수도 있습니다. API 내에서 IBM Cloud 환경의 모든 부분과 프로그래밍 방식으로 상호작용할 수 있으므로 SoftLayer API을(를) 사용하여 태스크를 자동화할 수 있습니다.

SoftLayer API는 원격 프로시저 호출 시스템입니다. 각 호출에는 API 엔드포인트로 데이터 전송 및 그에 대한 구조화된 데이터 수신이 포함됩니다. SoftLayer API에서 데이터를 전송하고 수신하는 데 사용되는 형식은 선택하는 API의 구현에 따라 달라집니다. SoftLayer API에서는 현재 데이터 전송을 위해 SOAP, XML-RPC 또는 REST를 사용합니다.

프로그래밍 방식으로 클래식 인프라에 대한 시스템 이벤트를 감사하려면 다음 예에 표시된 대로 SoftLayer API를 호출하십시오.

https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
                    resultLimit=0,50&
                    objectMask=mask[eventName,eventCreateDate,userType]

curl -g -u $SL_USER:$SL_APIKEY 'https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?objectMask=mask[eventName,eventCreateDate,userType]&resultLimit=0,50'

The output looks something like this, in this case just the first event in the list:

[
    {
        "eventCreateDate": "2021-03-29T14:41:55.444089-06:00",
        "eventName": "Login Successful",
        "userType": "CUSTOMER"
    }
  ]
import datetime
import SoftLayer

class example():

    def __init__(self):

        self.client = SoftLayer.Client()
        debugger = SoftLayer.DebugTransport(self.client.transport)
        self.client.transport = debugger

    def recentLogs(self):
        """REST API CALL
        'https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
            resultLimit=0,50&
            objectFilter={"eventCreateDate":{"operation":"greaterThanDate","options":[{"name":"date","value":["2018-04-18T00:00:00.0000-06:00"]}]}}'
        """
        _filter = {
            'eventCreateDate': {
                'operation': 'greaterThanDate',
                'options': [
                    {'name': 'date', 'value': [getDateString(30)]}
                ]
            }
        }
        for event in self.getAllObjects(_filter):
            printLogs(event)

    def systemLogs(self):
        """REST API CALL
        'https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
            resultLimit=0,50&
            objectFilter={"userType":{"operation":"SYSTEM"}}'
        """
        _filter = {'userType': {'operation': 'SYSTEM'}}
        for event in self.getAllObjects(_filter):
            printLogs(event)

    def loginLogs(self):
        """REST API CALL
        https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
            resultLimit=0,50&
            objectFilter={"eventName":{"operation":"^= Login"}}'
        """
        _filter = {
            'eventName': {
                'operation': '^= Login'
            }
        }
        for event in self.getAllObjects(_filter):
            printLogs(event)

    def allLogs(self):
        """REST API CALL
        'https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?resultLimit=0,50'
        """
        for event in self.getAllObjects(None):
            printLogs(event)


    def getAllObjects(self, _filter, limit=50, offset=0):
        """Pages through all results from the Event_Log. This might take long time."""
        notDone = True
        while notDone:
            events = self.client.call('SoftLayer_Event_Log', 'getAllObjects', filter=_filter, limit=limit, offset=offset)
            print("%s from getAllObjects, offset = %s" % (len(events), offset))

            for event in events:
                yield event
            if len(events) < limit:
                notDone = False
            offset = offset + limit
            notDone = False

    def debug(self):
        for call in self.client.transport.get_last_calls():
            print(self.client.transport.print_reproduceable(call))


def getDateString(self, delta=30):
    date_object = datetime.date.today() - datetime.timedelta(days=delta)
    return date_object.strftime("%Y-%m-%dT00:00:00.0000-06:00")

def printLogs(log):
    print("%s - %s - %s" % (log['eventName'],log['eventCreateDate'], log['userType']))

if __name__ == "__main__":
    main = example()
    main.allLogs()
    main.debug()
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.softlayer.api.ApiClient;
import com.softlayer.api.RestApiClient;
import com.softlayer.api.ResultLimit;
import com.softlayer.api.service.event.Log;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class EventLogExample {
  private final ApiClient client;
  private final Log.Service  logService;
  public EventLogExample() {
    String username = "set-me";
    String apiKey = "set-me";
    client = new RestApiClient().withCredentials(username, apiKey).withLoggingEnabled();
    logService = Log.service(client);
  }
  public static void main(String[] args) {
    EventLogExample eventLogExample = new EventLogExample();
    eventLogExample.getAllTypes();
    eventLogExample.getUserTypes();
    eventLogExample.allLogs();
    eventLogExample.loginLogs();
    eventLogExample.recentLogs();
    eventLogExample.systemLogs();
  }
  /**
   * Running GET on https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/AllEventObjectNames.json with no body
   */
  private void getAllTypes() {
    print(logService.getAllEventObjectNames());
  }
  /***
   * Running GET on https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/AllUserTypes.json with no body
   */
  private void getUserTypes() {
    print(logService.getAllUserTypes());
  }
  /***
   * Running GET on https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/AllObjects.json?resultLimit=0,50 with no body
   */
  private void systemLogs() {
    List<Log> logs=getAllEvents(false);
    String systemName="SYSTEM";
    List<Log> systemLogs = logs.stream()
            .filter(log -> systemName.equalsIgnoreCase(log.getEventName()))
            .collect(Collectors.toList());
    printEventLogs(systemLogs);
  }
  /**
   * Running GET on https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/AllObjects.json?resultLimit=0,50 with no body
   */
  private void recentLogs() {
    LocalDate daysAgo = LocalDate.now().minusDays(30);
    List<Log> logs=getAllEvents(false);
    List<Log> recentLogs = logs.stream()
            .filter(log -> log.getEventCreateDate()
                    .toZonedDateTime()
                    .toLocalDate()
                    .compareTo(daysAgo)>0)
            .collect(Collectors.toList());
    printEventLogs(recentLogs);
  }
  /**
   * Running GET on https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/AllObjects.json?resultLimit=0,50 with no body
   */
  private void loginLogs() {
    List<Log> logs=getAllEvents(false);
    String loginName="login";
    List<Log> loginLogs = logs.stream()
            .filter(log -> log
                    .getEventName()
                    .toLowerCase()
                    .contains(loginName))
            .collect(Collectors.toList());
    printEventLogs(loginLogs);
  }
  /**
   * Running GET on https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/AllObjects.json?resultLimit=0,50 with no body
   */
  private void allLogs() {
    printEventLogs(getAllEvents(false));
  }
  /**
   * Pages through all results from the Event_Log. This might take long time.
   */
  private List<Log> getAllEvents(boolean allEvents) {
    List<Log> result=new ArrayList<>();
    int limit =50;
    int offset =0;
    ResultLimit resultLimit =new ResultLimit(offset,limit);
    boolean iterateEvents=true;
    while(iterateEvents) {
      logService.setResultLimit(resultLimit);
      List<Log> logs = logService.getAllObjects();
      result.addAll(logs);
      if (logs.size() < resultLimit.limit) {
        iterateEvents = false;
      }
      offset+=limit;
      resultLimit=new ResultLimit(offset,limit);
      iterateEvents=iterateEvents&&allEvents;
    }
    return result;
  }
  void print(Object object) {
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String json;
    json = gson.toJson(object);
    System.out.println(json);
  }
  void printEventLogs(List<Log> logs){
    for (Log event :logs) {
      System.out.println(String.format("%s - %s - %s",
                      event.getEventName(),
                      event.getEventCreateDate().getTime(),
                      event.getUserType()));
    }
  }
}
package main

import (
	"encoding/json"
	"fmt"
	"github.com/softlayer/softlayer-go/datatypes"
	"github.com/softlayer/softlayer-go/filter"
	"github.com/softlayer/softlayer-go/services"
	"github.com/softlayer/softlayer-go/session"
	"time"
)

// Session created using values set in the environment, or from the local configuration file (i.e. ~/.softlayer).
var sess = session.New()

// Set the limit number of events that the API retrieves in each SoftLayer_Event_Log::getAllObjects  method call.
var pagination = 50

// Set the max number of events to retrieve in each log example function.
var maxNumberOfEvents =200

func main() {

	sess.Debug = true

	//shows the all user type events
	getEventUserTypes()
	userType:="EMPLOYEE"
	//shows the events with names is a userType value
	getLogsByUserType(userType)

	//shows the all user type events
	getEventNames()
	eventName:="Authentication"
	//shows the events which names contain the eventName value
	getLogsByName(eventName)

	//shows the events created from a specific number of days ago
	daysAgo:=30
	getRecentLogs(daysAgo)

	//shows the system logs
	getSystemLogs()

	//shows the login logs
	getLoginLogs()
}

/**
Shows the Event Logs by user type.
Request URL:
GET https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
objectFilter={"userType":{"operation":"userType"}}&
objectMask=mask[userType,eventName,eventCreateDate]&
resultLimit=0,50
*/
func getLogsByUserType(eventUserType string) {
	filter := filter.Build(filter.Path("userType").Eq(eventUserType))
	mask:="userType,eventName,eventCreateDate"
	systemEvents:=getAllEvents(filter,mask,pagination,maxNumberOfEvents)
	printLogs(systemEvents)
}

/**
Shows the Event Logs which eventName contains nameQuery value
RequestURL:
GET https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
objectFilter={"eventName":{"operation":"^=+nameQuery"}}&
objectMask=mask[userType;eventName,eventCreateDate]&
resultLimit=0,50
*/
func
getLogsByName(nameQuery string){
	filterQuery:=fmt.Sprintf("^= %s",nameQuery)
	filter := filter.Build(filter.Path("eventName").Eq(filterQuery))
	mask:="userType;eventName,eventCreateDate"
	eventLogs :=getAllEvents(filter,mask,pagination,maxNumberOfEvents)
	printLogs(eventLogs)
}


/**
Shows the SYSTEM Logs.
Request URL:
GET https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
objectFilter={"userType":{"operation":"SYSTEM"}}&
objectMask=mask[userType,eventName,eventCreateDate]&
resultLimit=0,50
*/
func getSystemLogs(){
	getLogsByUserType("SYSTEM")
}

/**
Shows the Login Logs
RequestURL:
GET https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
objectFilter={"eventName":{"operation":"^=+Login"}}&
objectMask=mask[userType;eventName,eventCreateDate]&
resultLimit=0,50
*/
func getLoginLogs(){
	getLogsByName("Login")
}

/**
Shows the recent Logs, based on a number of days ago.
Request URL:
GET https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
objectFilter={"eventCreateDate":{"operation":"greaterThanDate",
	"options":[{"name":"date","value":["2021-04-24T00:00:00.0000-06:00"]}]}}&
objectMask=mask[userType;eventName,eventCreateDate]&
resultLimit=0,50
*/
func getRecentLogs(daysAgo int){
	offsetDate :=getDateString(-daysAgo)
	filterObject:=filter.Build(filter.Path("eventCreateDate").DateAfter(offsetDate))
	mask:="userType;eventName,eventCreateDate"
	recentEvents:=getAllEvents(filterObject,mask,pagination,maxNumberOfEvents)
	printLogs(recentEvents)
}

/**
Pages through all results from the Event_Log. This might take long time.
*/
func getAllEvents(
	filter string,
	mask string,
	pagination int,
	maxNumberOfEvents int,
) (resp []datatypes.Event_Log) {
	limit:=pagination
	offset:=0
	eventsSize:=limit
	var allEvents []datatypes.Event_Log
	for eventsSize<=maxNumberOfEvents {
		events := getAllObjects(limit,offset,filter,mask)
		// return if the events are a list of empty structure like [{}]
		if events[0]==(datatypes.Event_Log{}){
			return allEvents
		}
		allEvents=append(allEvents, events...)
		eventsSize=eventsSize+pagination
	}
	return allEvents
}

/**
Request URL:
GET https://api.softlayer.com/rest/v3.1/SoftLayer_Event_Log/getAllObjects.json?
objectFilter= filter &
objectMask= mask &
resultLimit=0,50

It returns an array of Event_Log encountered.
*/
func getAllObjects(
	limit int,
	offset int,
	filter string,
	mask string,
) (resp []datatypes.Event_Log) {
	var service = services.GetEventLogService(sess)
	result, err := service.
		Limit(limit).
		Offset(offset).
		Filter(filter).
		Mask(mask).
		GetAllObjects()
	if err != nil {
		fmt.Printf("\n Unable to get Events:\n - %s\n", err)
		return
	}

	return result
}

/**
Shows the Event Logs Names.
*/
func getEventNames(){
	var service = services.GetEventLogService(sess)
	result, err := service.GetAllEventObjectNames()
	if err != nil {
		fmt.Printf("\n Unable to get Events:\n - %s\n", err)
		return
	}
	printAsJsonFormat(result)
}

/**
Shows the Event Logs User Types.
*/
func getEventUserTypes() {
	var service = services.GetEventLogService(sess)
	result, err := service.GetAllUserTypes()
	if err != nil {
		fmt.Printf("\n Unable to get User types:\n - %s\n", err)
		return
	}
	printAsJsonFormat(result)
}

/**
Gets a date offset in days determined by offsetDays value.
It returns a string date with SL API date filtering format.
*/
func getDateString(offsetDays int) (resp string) {
	years:=0
	months:=0
	days:= offsetDays
	offsetTime:=time.Now().AddDate(years,months,days)
	return fmt.Sprintf(
		"%d-%02d-%02dT00:00:00.0000-06:00",
		offsetTime.Year(),
		offsetTime.Month(),
		offsetTime.Day())
}

/**
Prints the data as format JSON.
*/
func printAsJsonFormat(data interface{}){
	jsonData, jsonErr := json.MarshalIndent(data, "", "    ")
	if jsonErr != nil {
		fmt.Println(jsonErr)
		return
	}
	println(string(jsonData))
}

/**
Prints the Event Logs.
*/
func printLogs(logs []datatypes.Event_Log){
	fmt.Printf("| %35s | %25s |%10s |\n","Event Name","Event Create Date","User Type")
	for _, log := range logs {
		if log!=(datatypes.Event_Log{}){
			fmt.Printf("| %35s ", *log.EventName)
			fmt.Printf("| %25s ", log.EventCreateDate)
			fmt.Printf("| %10s |\n", *log.UserType)
		}
	}
}

모든 이벤트 로그를 가져오려면 SoftLayer_Event_Log::getAllObjects()를 사용하십시오. 이 경우, 페이지 매김 한계 resultLimit=0,50을(를) 사용하여 처음 50개의 이벤트만 리턴됩니다. 자세한 정보는 SoftLayer API에서 결과 한계 사용을 참조하십시오. 기타 로컬 필드와 리턴된 정보의 양을 제한하는 mask[eventName,eventCreateDate,userType] 마스크가 이 예에 표시됩니다.

이 예에서는 SoftLayer_Event_Log에서 데이터를 가져오는 몇 가지 방법을 다룹니다. 많은 로그가 있을 수 있으므로 recentLogs 함수와 같은 필터를 사용하여 이벤트 검색 범위를 제한할 수 있습니다.

이 예에서는 SoftLayer_Event_Log에서 데이터를 가져오는 몇 가지 방법을 다룹니다. 최신 SoftLayer API Client for Java 버전(이 예 공개 당시의 v0.3.2)은 SoftLayer API에서 오브젝트 필터를 지원하지 않으므로 대신 프로그래밍 방식의 필터가 사용됩니다.

이 예에서는 SoftLayer_Event_Log에서 데이터를 가져오는 몇 가지 방법을 다룹니다. 많은 로그가 있을 수 있으므로 getRecentLogs 함수와 같은 필터를 사용하여 이벤트 검색 범위를 제한할 수 있습니다. 이 예wp에서는 maxNumberOfEvents 값을 사용하여 검색되는 이벤트 로그 수를 제한합니다.

SoftLayer API 및 가상 서버 API에 관한 자세한 정보는 SoftLayer® Development Network의다음 리소스를 참조하십시오.

API 사용 예는 다음 리소스를 참조하십시오.