1 /*
2 * Copyright 2020 Google Inc.
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 * https://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 /*
18 * Notes
19 *
20 */
21
22 /*
23 * Imports
24 */
25
26 import java.io.File
27 import trebuchet.model.Model
28 import trebuchet.extras.parseTrace
29 import trebuchet.model.base.Slice
30 import trebuchet.model.base.SliceGroup
31 import trebuchet.queries.slices.slices
32 import java.io.PrintStream
33
34 /*
35 * Constants
36 */
37
38 /*
39 * Class Definition
40 */
41
42 /*
43 * Class Extensions
44 */
45
46 /*
47 * Helper Functions
48 */
49
Doublenull50 fun Double.durationString(): String {
51 return "%.3f ms".format(this * 1000)
52 }
53
measureServiceStartupnull54 fun measureServiceStartup(
55 model: Model,
56 userId: Int = 0,
57 count: Int = 0,
58 output: PrintStream = System.out) {
59
60 var stages = arrayOf("Start", "Switch", "Unlock")
61
62 for (item in stages) {
63 model.slices().filter {
64 it.name.contains("ssm." + item + "User-" + userId) && !it.name.contains("ssm.on")
65 }.forEach {
66 output.println(item + "User-" + userId + " duration: " + it.duration.durationString())
67 }
68
69 model.slices().filter {
70 it.name.contains("ssm.on" + item + "User-" + userId)
71 }.sortedByDescending {
72 it.duration
73 }.take(count).forEach {
74 output.println(it.name.removePrefix("ssm.on" + item + "User-" + userId + " ") + " " + it.duration.durationString())
75 }
76 }
77 }
78
79 /*
80 * Main Function
81 */
82
mainnull83 fun main(args: Array<String>) {
84 if (args.isEmpty()) {
85 println("Usage: UserSwitchAnalyzerKt <trace_filename> [-u user_Id] [-o output_filename] [-c service_count]")
86 return
87 }
88
89 val input = args[0]
90
91 println("Opening ${input}")
92 val trace = parseTrace(File(input), verbose = true)
93
94 var output = System.out
95 var userId = -1;
96 var serviceCount = 5;
97
98 // Parse optional arguments
99 var nextArg = 1
100 while (nextArg < args.size) {
101 var arg = args[nextArg++]
102 var value = args[nextArg++]
103 when (arg) {
104 "-u" -> userId = value.toInt()
105 "-c" -> serviceCount = value.toInt()
106 "-o" -> {
107 output = PrintStream(File(value).outputStream())
108 }
109 else -> println("invalid option: ${arg}")
110 }
111 }
112
113 if (userId == -1) {
114 println("user Id not provided")
115 return
116 }
117
118 measureServiceStartup(trace, userId, serviceCount, output)
119 }
120