Skip to content

Commit 3bf014d

Browse files
minni31Minni Mittal
andauthored
YARN-8859. Add audit logs for router service (#3607)
Co-authored-by: Minni Mittal <mimittal@microsoft.com>
1 parent 43afd17 commit 3bf014d

File tree

4 files changed

+473
-26
lines changed

4 files changed

+473
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.yarn.server.router;
20+
21+
import org.apache.hadoop.yarn.api.records.ApplicationId;
22+
import org.apache.hadoop.yarn.server.federation.store.records.SubClusterId;
23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
25+
26+
/**
27+
* Manages Router audit logs.
28+
* Audit log format is written as key=value pairs. Tab separated.
29+
*/
30+
public class RouterAuditLogger {
31+
private static final Logger LOG =
32+
LoggerFactory.getLogger(RouterAuditLogger.class);
33+
34+
private RouterAuditLogger() {
35+
}
36+
37+
enum Keys {USER, OPERATION, TARGET, RESULT, IP, PERMISSIONS, DESCRIPTION, APPID, SUBCLUSTERID}
38+
39+
public static class AuditConstants {
40+
static final String SUCCESS = "SUCCESS";
41+
static final String FAILURE = "FAILURE";
42+
static final String KEY_VAL_SEPARATOR = "=";
43+
static final char PAIR_SEPARATOR = '\t';
44+
45+
public static final String GET_NEW_APP = "Get New App";
46+
public static final String SUBMIT_NEW_APP = "Submit New App";
47+
public static final String FORCE_KILL_APP = "Force Kill App";
48+
public static final String GET_APP_REPORT = "Get Application Report";
49+
}
50+
51+
/**
52+
* Create a readable and parseable audit log string for a successful event.
53+
*
54+
* @param user User who made the service request to the Router
55+
* @param operation Operation requested by the user.
56+
* @param target The target on which the operation is being performed.
57+
* @param appId Application Id in which operation was performed.
58+
*
59+
* <br><br>
60+
* Note that the {@link RouterAuditLogger} uses tabs ('\t') as a key-val
61+
* delimiter and hence the value fields should not contains tabs ('\t').
62+
*/
63+
public static void logSuccess(String user, String operation, String target,
64+
ApplicationId appId) {
65+
if (LOG.isInfoEnabled()) {
66+
LOG.info(createSuccessLog(user, operation, target, appId, null));
67+
}
68+
}
69+
70+
/**
71+
* Create a readable and parseable audit log string for a successful event.
72+
*
73+
* @param user User who made the service request to the Router
74+
* @param operation Operation requested by the user.
75+
* @param target The target on which the operation is being performed.
76+
* @param appId Application Id in which operation was performed.
77+
* @param subClusterId Subcluster Id in which operation is performed.
78+
*
79+
* <br><br>
80+
* Note that the {@link RouterAuditLogger} uses tabs ('\t') as a key-val
81+
* delimiter and hence the value fields should not contains tabs ('\t').
82+
*/
83+
public static void logSuccess(String user, String operation, String target,
84+
ApplicationId appId, SubClusterId subClusterId) {
85+
if (LOG.isInfoEnabled()) {
86+
LOG.info(createSuccessLog(user, operation, target, appId, subClusterId));
87+
}
88+
}
89+
90+
/**
91+
* A helper api for creating an audit log for a successful event.
92+
*/
93+
static String createSuccessLog(String user, String operation, String target,
94+
ApplicationId appId, SubClusterId subClusterID) {
95+
StringBuilder b =
96+
createStringBuilderForSuccessEvent(user, operation, target);
97+
if (appId != null) {
98+
add(Keys.APPID, appId.toString(), b);
99+
}
100+
if (subClusterID != null) {
101+
add(Keys.SUBCLUSTERID, subClusterID.toString(), b);
102+
}
103+
return b.toString();
104+
}
105+
106+
/**
107+
* A helper function for creating the common portion of a successful
108+
* log message.
109+
*/
110+
private static StringBuilder createStringBuilderForSuccessEvent(String user,
111+
String operation, String target) {
112+
StringBuilder b = new StringBuilder();
113+
start(Keys.USER, user, b);
114+
add(Keys.OPERATION, operation, b);
115+
add(Keys.TARGET, target, b);
116+
add(Keys.RESULT, AuditConstants.SUCCESS, b);
117+
return b;
118+
}
119+
120+
/**
121+
* Create a readable and parseable audit log string for a failed event.
122+
*
123+
* @param user User who made the service request.
124+
* @param operation Operation requested by the user.
125+
* @param perm Target permissions.
126+
* @param target The target on which the operation is being performed.
127+
* @param description Some additional information as to why the operation
128+
* failed.
129+
*
130+
* <br><br>
131+
* Note that the {@link RouterAuditLogger} uses tabs ('\t') as a key-val
132+
* delimiter and hence the value fields should not contains tabs ('\t').
133+
*/
134+
public static void logFailure(String user, String operation, String perm,
135+
String target, String description) {
136+
if (LOG.isInfoEnabled()) {
137+
LOG.info(
138+
createFailureLog(user, operation, perm, target, description, null,
139+
null));
140+
}
141+
}
142+
143+
/**
144+
* Create a readable and parseable audit log string for a failed event.
145+
*
146+
* @param user User who made the service request.
147+
* @param operation Operation requested by the user.
148+
* @param perm Target permissions.
149+
* @param target The target on which the operation is being performed.
150+
* @param description Some additional information as to why the operation
151+
* failed.
152+
* @param appId Application Id in which operation was performed.
153+
*
154+
* <br><br>
155+
* Note that the {@link RouterAuditLogger} uses tabs ('\t') as a key-val
156+
* delimiter and hence the value fields should not contains tabs ('\t').
157+
*/
158+
public static void logFailure(String user, String operation, String perm,
159+
String target, String description, ApplicationId appId) {
160+
if (LOG.isInfoEnabled()) {
161+
LOG.info(
162+
createFailureLog(user, operation, perm, target, description, appId,
163+
null));
164+
}
165+
}
166+
167+
/**
168+
* Create a readable and parseable audit log string for a failed event.
169+
*
170+
* @param user User who made the service request.
171+
* @param operation Operation requested by the user.
172+
* @param perm Target permissions.
173+
* @param target The target on which the operation is being performed.
174+
* @param description Some additional information as to why the operation
175+
* failed.
176+
* @param appId Application Id in which operation was performed.
177+
* @param subClusterId SubCluster Id in which operation was performed.
178+
*
179+
* <br><br>
180+
* Note that the {@link RouterAuditLogger} uses tabs ('\t') as a key-val
181+
* delimiter and hence the value fields should not contains tabs ('\t').
182+
*/
183+
public static void logFailure(String user, String operation, String perm,
184+
String target, String description, ApplicationId appId,
185+
SubClusterId subClusterId) {
186+
if (LOG.isInfoEnabled()) {
187+
LOG.info(
188+
createFailureLog(user, operation, perm, target, description, appId,
189+
subClusterId));
190+
}
191+
}
192+
193+
/**
194+
* A helper api for creating an audit log for a failure event.
195+
*/
196+
static String createFailureLog(String user, String operation, String perm,
197+
String target, String description, ApplicationId appId,
198+
SubClusterId subClusterId) {
199+
StringBuilder b =
200+
createStringBuilderForFailureLog(user, operation, target, description,
201+
perm);
202+
if (appId != null) {
203+
add(Keys.APPID, appId.toString(), b);
204+
}
205+
if (subClusterId != null) {
206+
add(Keys.SUBCLUSTERID, subClusterId.toString(), b);
207+
}
208+
return b.toString();
209+
}
210+
211+
/**
212+
* A helper function for creating the common portion of a failure
213+
* log message.
214+
*/
215+
private static StringBuilder createStringBuilderForFailureLog(String user,
216+
String operation, String target, String description, String perm) {
217+
StringBuilder b = new StringBuilder();
218+
start(Keys.USER, user, b);
219+
add(Keys.OPERATION, operation, b);
220+
add(Keys.TARGET, target, b);
221+
add(Keys.RESULT, AuditConstants.FAILURE, b);
222+
add(Keys.DESCRIPTION, description, b);
223+
add(Keys.PERMISSIONS, perm, b);
224+
return b;
225+
}
226+
227+
/**
228+
* Adds the first key-val pair to the passed builder in the following format
229+
* key=value.
230+
*/
231+
static void start(Keys key, String value, StringBuilder b) {
232+
b.append(key.name()).append(AuditConstants.KEY_VAL_SEPARATOR).append(value);
233+
}
234+
235+
/**
236+
* Appends the key-val pair to the passed builder in the following format
237+
* <pair-delim>key=value.
238+
*/
239+
static void add(Keys key, String value, StringBuilder b) {
240+
b.append(AuditConstants.PAIR_SEPARATOR).append(key.name())
241+
.append(AuditConstants.KEY_VAL_SEPARATOR).append(value);
242+
}
243+
}

0 commit comments

Comments
 (0)