审计经典基础架构的系统事件
如果您拥有经典基础架构帐户,那么可以通过查看审计日志来监视存储复制事件。 审计日志会跟踪每个用户的交互,如登录尝试、端口速度更新、电源重新启动以及由 IBM Cloud 基础架构支持人员进行的交互。
在控制台中查看审计日志
要查看审计日志,请转到 IBM Cloud® 控制台中的 Manage > Account 并选择 Audit log。 审计日志初始会显示帐户上的用户所做的最后 25 个交互。 您可以随时查看多达 200 个交互。 展开“每页项数”菜单可查看更多结果。
查看用户的访问日志
在审计日志页面中,还可以查看由特定用户进行的每次访问尝试的数据。 日志会显示每次访问尝试的日期、时间戳和 IP 地址。 使用以下步骤查看用户的访问日志。
- 转至 IBM Cloud 控制台中的 管理 > 帐户,然后选择 审计日志。
- 然后,筛选用户,选择要查看的时间范围,并选择对象类型。
每个用户的访问日志都会按日期显示该用户进行的访问尝试,以及用于进行访问尝试的 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 Java 客户端(v0.3.2
发布本示例时)不支持 SoftLayer API 中的对象筛选器,因此使用了编程筛选器。
此示例处理从 SoftLayer_Event_Log
中拉取数据的几种方法。 可能有许多日志,因此通过使用过滤器 (如 getRecentLogs
函数),可以限制搜索事件的返回距离。 此示例使用 maxNumberOfEvents
值来限制检索的事件日志数。
有关 SoftLayer API 和虚拟服务器 API 的更多信息,请参阅 SoftLayer® Development Network中的以下资源:
有关 API 用法示例,请参阅以下资源: