• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.util;
18 
19 import android.text.TextUtils;
20 import android.util.LocalLog;
21 import android.util.Log;
22 
23 import java.io.FileDescriptor;
24 import java.io.PrintWriter;
25 import java.util.StringJoiner;
26 
27 
28 /**
29  * Class to centralize logging functionality for tethering.
30  *
31  * All access to class methods other than dump() must be on the same thread.
32  *
33  * @hide
34  */
35 public class SharedLog {
36     private final static int DEFAULT_MAX_RECORDS = 500;
37     private final static String COMPONENT_DELIMITER = ".";
38 
39     private enum Category {
40         NONE,
41         ERROR,
42         MARK,
43         WARN,
44     };
45 
46     private final LocalLog mLocalLog;
47     // The tag to use for output to the system log. This is not output to the
48     // LocalLog because that would be redundant.
49     private final String mTag;
50     // The component (or subcomponent) of a system that is sharing this log.
51     // This can grow in depth if components call forSubComponent() to obtain
52     // their SharedLog instance. The tag is not included in the component for
53     // brevity.
54     private final String mComponent;
55 
SharedLog(String tag)56     public SharedLog(String tag) {
57         this(DEFAULT_MAX_RECORDS, tag);
58     }
59 
SharedLog(int maxRecords, String tag)60     public SharedLog(int maxRecords, String tag) {
61         this(new LocalLog(maxRecords), tag, tag);
62     }
63 
SharedLog(LocalLog localLog, String tag, String component)64     private SharedLog(LocalLog localLog, String tag, String component) {
65         mLocalLog = localLog;
66         mTag = tag;
67         mComponent = component;
68     }
69 
forSubComponent(String component)70     public SharedLog forSubComponent(String component) {
71         if (!isRootLogInstance()) {
72             component = mComponent + COMPONENT_DELIMITER + component;
73         }
74         return new SharedLog(mLocalLog, mTag, component);
75     }
76 
dump(FileDescriptor fd, PrintWriter writer, String[] args)77     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
78         mLocalLog.readOnlyLocalLog().dump(fd, writer, args);
79     }
80 
81     //////
82     // Methods that both log an entry and emit it to the system log.
83     //////
84 
e(Exception e)85     public void e(Exception e) {
86         Log.e(mTag, record(Category.ERROR, e.toString()));
87     }
88 
e(String msg)89     public void e(String msg) {
90         Log.e(mTag, record(Category.ERROR, msg));
91     }
92 
i(String msg)93     public void i(String msg) {
94         Log.i(mTag, record(Category.NONE, msg));
95     }
96 
w(String msg)97     public void w(String msg) {
98         Log.w(mTag, record(Category.WARN, msg));
99     }
100 
101     //////
102     // Methods that only log an entry (and do NOT emit to the system log).
103     //////
104 
log(String msg)105     public void log(String msg) {
106         record(Category.NONE, msg);
107     }
108 
logf(String fmt, Object... args)109     public void logf(String fmt, Object... args) {
110         log(String.format(fmt, args));
111     }
112 
mark(String msg)113     public void mark(String msg) {
114         record(Category.MARK, msg);
115     }
116 
record(Category category, String msg)117     private String record(Category category, String msg) {
118         final String entry = logLine(category, msg);
119         mLocalLog.log(entry);
120         return entry;
121     }
122 
logLine(Category category, String msg)123     private String logLine(Category category, String msg) {
124         final StringJoiner sj = new StringJoiner(" ");
125         if (!isRootLogInstance()) sj.add("[" + mComponent + "]");
126         if (category != Category.NONE) sj.add(category.toString());
127         return sj.add(msg).toString();
128     }
129 
130     // Check whether this SharedLog instance is nominally the top level in
131     // a potential hierarchy of shared logs (the root of a tree),
132     // or is a subcomponent within the hierarchy.
isRootLogInstance()133     private boolean isRootLogInstance() {
134         return TextUtils.isEmpty(mComponent) || mComponent.equals(mTag);
135     }
136 }
137