Guest User

XenDesktop 7 - User session report fix

a guest
May 26th, 2016
249
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <title>User Session Detail | Splunk</title>
  7. <link rel="shortcut icon" href="{{SPLUNKWEB_URL_PREFIX}}/static/img/favicon_enterprise.ico" />
  8. <link rel="stylesheet" type="text/css" href="{{SPLUNKWEB_URL_PREFIX}}/static/css/bootstrap.min.css" />
  9. <link rel="stylesheet" type="text/css" media="all" href="{{SPLUNKWEB_URL_PREFIX}}/static/css/pages/dashboard-simple-bootstrap.min.css" />
  10. <link rel="stylesheet" type="text/css" media="all" href="{{SPLUNKWEB_URL_PREFIX}}/static/app/TemplateForXenDesktop7/dashboard.css" />
  11. <link rel="stylesheet" type="text/css" media="all" href="{{SPLUNKWEB_URL_PREFIX}}/static/app/TemplateForXenDesktop7/session-user.css" />
  12. <!--[if IE 7]><link rel="stylesheet" href="{{SPLUNKWEB_URL_PREFIX}}/static/css/sprites-ie7.css" /><![endif]-->
  13. </head>
  14.  
  15. <body class="simplexml preload">
  16.  
  17. <div class="header">
  18. <div id="placeholder-splunk-bar">
  19. <a href="{{SPLUNKWEB_URL_PREFIX}}/app/launcher/home" class="brand" title="splunk &gt; listen to your data">splunk<strong>&gt;</strong></a>
  20. </div>
  21. <div id="placeholder-app-bar"></div>
  22. </div>
  23.  
  24. <div class="dashboard-body container-fluid main-section-body" data-role="main">
  25.  
  26. <div class="dashboard-header clearfix">
  27. <h2>User Session Detail</h2>
  28. <p class="description"></p>
  29. </div>
  30.  
  31. <div class="fieldset">
  32. <div class="input input-timerangepicker" id="field1">
  33. <label>Time Range:</label>
  34. </div>
  35.  
  36. <div class="input input-text" id="field2">
  37. <label>User Name:</label>
  38. </div>
  39.  
  40. <div class="input input-text" id="field3">
  41. <label>Machine Name:</label>
  42. </div>
  43.  
  44. <div class="input form-submit" id="search_btn">
  45. <button class="btn btn-primary submit">Search</button>
  46. </div>
  47. </div>
  48.  
  49. <div class="dashboard-row dashboard-row1">
  50. <div class="dashboard-cell" id="cell-detail" style="width: 100%;">
  51. <div class="dashboard-panel" style="min-height: 100px">
  52. <div class="panel-element-row">
  53.  
  54. <div class="dashboard-element dataview" style="width: 100%">
  55. <div class="panel-head">
  56. <h3>Session Details</h3>
  57. </div>
  58. <div class="panel-body">
  59. <div id="user-session-details"></div>
  60. </div>
  61. </div>
  62.  
  63. </div>
  64. </div>
  65. </div>
  66.  
  67. <div class="dashboard-cell" id="cell-map" style="width: 0px; visibility: hidden; overflow: hidden">
  68. <div class="dashboard-panel">
  69. <div class="panel-element-row">
  70. <div class="dashboard-element map" id="map-login" style="width: 100%">
  71. <div class="panel-head">
  72. <h3>Last Login Location</h3>
  73. </div>
  74. <div class="panel-body"></div>
  75. </div>
  76. </div>
  77. </div>
  78. </div>
  79.  
  80. </div>
  81.  
  82. <div class="dashboard-row dashboard-row2">
  83. <div class="dashboard-cell" style="width: 33.33%;">
  84. <div class="dashboard-panel clearfix">
  85. <div class="panel-element-row">
  86. <div class="dashboard-element chart" id="chartCpu" style="width: 100%">
  87. <div class="panel-head">
  88. <h3>Avg. Processor Time</h3>
  89. </div>
  90. <div class="panel-body"></div>
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. <div class="dashboard-cell" style="width: 33.33%;">
  96. <div class="dashboard-panel clearfix">
  97. <div class="panel-element-row">
  98. <div class="dashboard-element chart" id="chartMem" style="width: 100%">
  99. <div class="panel-head">
  100. <h3>Avg. Memory Usage in Bytes</h3>
  101. </div>
  102. <div class="panel-body"></div>
  103. </div>
  104. </div>
  105. </div>
  106. </div>
  107. <div class="dashboard-cell" style="width: 33.33%;">
  108. <div class="dashboard-panel clearfix">
  109. <div class="panel-element-row">
  110. <div class="dashboard-element chart" id="chartIops" style="width: 100%">
  111. <div class="panel-head">
  112. <h3>Avg. IOPS</h3>
  113. </div>
  114. <div class="panel-body"></div>
  115. </div>
  116. </div>
  117. </div>
  118. </div>
  119. </div>
  120.  
  121. <div class="dashboard-row dashboard-row3">
  122. <div class="dashboard-cell" style="width: 100%;">
  123. <div class="dashboard-panel clearfix">
  124. <div class="panel-element-row">
  125.  
  126. <div class="dashboard-element table" id="table-user-processes" style="width: 100%">
  127. <div class="panel-head">
  128. <h3>Process Details</h3>
  129. </div>
  130. <div class="panel-body"></div>
  131. </div>
  132.  
  133. </div>
  134. </div>
  135. </div>
  136. </div>
  137.  
  138. </div>
  139.  
  140. <div class="footer"></div>
  141.  
  142. <script src="{{SPLUNKWEB_URL_PREFIX}}/config?autoload=1"></script>
  143. <script src="{{SPLUNKWEB_URL_PREFIX}}/static/js/i18n.js"></script>
  144. <script src="{{SPLUNKWEB_URL_PREFIX}}/static/js/build/simplexml.min/config.js"></script>
  145.  
  146. <script type="text/x-underscore-tmpl" id="user-session-template" style="display:none">
  147. <table id="user-session-table">
  148. <tbody>
  149.  
  150. <%
  151. for(var i=0, l=results.length; i<l; i++) {
  152. var line=results[i];
  153. for(var key in line) {
  154. var attrName = key;
  155. var attrValue = line[key];
  156. %>
  157. <tr>
  158. <td><%= attrName %></td>
  159. <td><%= attrValue %></td>
  160. </tr>
  161. <%
  162. }
  163. }
  164. %>
  165.  
  166. </tbody>
  167. </table>
  168. </script>
  169.  
  170. <script type="text/javascript">
  171.  
  172. require.config({
  173. baseUrl: "{{SPLUNKWEB_URL_PREFIX}}/static/js",
  174. waitSeconds: 0 // Disable require.js load timeout
  175. });
  176. require([
  177. "splunkjs/mvc",
  178. "splunkjs/mvc/utils",
  179. "splunkjs/mvc/tokenutils",
  180. "underscore",
  181. "jquery",
  182. "splunkjs/mvc/simplexml",
  183. "splunkjs/mvc/headerview",
  184. "splunkjs/mvc/footerview",
  185. "splunkjs/mvc/simplexml/dashboard",
  186. "splunkjs/mvc/simplexml/element/chart",
  187. "splunkjs/mvc/simplexml/element/html",
  188. "splunkjs/mvc/simplexml/element/map",
  189. "splunkjs/mvc/simplexml/element/single",
  190. "splunkjs/mvc/simplexml/element/table",
  191. "splunkjs/mvc/simpleform/input/text",
  192. "splunkjs/mvc/simpleform/input/timerange",
  193. "splunkjs/mvc/simpleform/input/submit",
  194. "splunkjs/mvc/searchmanager",
  195. "splunkjs/mvc/postprocessmanager",
  196. "splunkjs/mvc/simplexml/urltokenmodel",
  197. "splunkjs/mvc/dataview"
  198. ],
  199. function(
  200. mvc,
  201. utils,
  202. TokenUtils,
  203. _,
  204. $,
  205. DashboardController,
  206. HeaderView,
  207. FooterView,
  208. Dashboard,
  209. ChartElement,
  210. HtmlElement,
  211. MapElement,
  212. SingleElement,
  213. TableElement,
  214. TextInput,
  215. TimeRangeInput,
  216. SubmitButton,
  217. SearchManager,
  218. PostProcessManager,
  219. UrlTokenModel,
  220. DataView) {
  221.  
  222. // AUTO-COMPILED JAVASCRIPT
  223. var pageLoading = true;
  224.  
  225. //
  226. // Create form token namespaces
  227. //
  228. var urlTokenModel = new UrlTokenModel();
  229. mvc.Components.registerInstance('url', urlTokenModel);
  230. var defaultTokenModel = mvc.Components.getInstance('default', {create: true});
  231. var submittedTokenModel = mvc.Components.getInstance('submitted', {create: true});
  232.  
  233. urlTokenModel.on('url:navigate', function() {
  234. defaultTokenModel.set(urlTokenModel.toJSON());
  235. if (!_.isEmpty(urlTokenModel.toJSON()) && !_.all(urlTokenModel.toJSON(), _.isUndefined)){
  236. submitTokens();
  237. } else {
  238. submittedTokenModel.clear();
  239. }
  240. });
  241.  
  242. // Initialize non-input tokens
  243. defaultTokenModel.set(urlTokenModel.toJSON());
  244.  
  245. var defaultUpdate = {};
  246.  
  247. var submitTokens = function() {
  248. submitTokensSoon(pageLoading); // captures from enclosing scope before debounce
  249. };
  250.  
  251. var submitTokensSoon = _.debounce(function(updateHistory) {
  252. submittedTokenModel.set(defaultTokenModel.toJSON());
  253. urlTokenModel.saveOnlyWithPrefix('form\.', defaultTokenModel.toJSON(), {
  254. replaceState: updateHistory
  255. });
  256. });
  257.  
  258. //***********************************
  259. // Session Detail Search
  260. //***********************************
  261. var searchUserSession = new SearchManager({
  262. "id": "searchUserSession",
  263. "cancelOnUnload": true,
  264. "latest_time": "$latest$",
  265. "earliest_time": "$earliest$",
  266. "search": '`xd_index` sourcetype=xendesktop:*:session MachineName="$machinename$" UserName="$username$" | \
  267. stats latest(UserName) AS "User Name" latest(MachineName) AS "Machine Name" latest(_time) AS CurrentTime latest(StartTime) AS StartTime latest(ClientName) AS "Client Name" \
  268. latest(ClientVersion) AS "Client Version" latest(SessionKey) AS "Session Key" latest(ClientAddress) AS "Client Address" latest(CatalogName) AS "Catalog Name" \
  269. latest(ControllerDNSName) AS "Controller" latest(DesktopGroupName) AS "Desktop Group" latest(DesktopKind) AS "Destktop Kind" latest(EstablishmentDuration) AS "Establishment Duration" \
  270. latest(OSType) AS "OS Type" latest(SessionType) AS "Session Type" | \
  271. eval "Start Time" = strftime(StartTime, "%m/%d/%Y %H:%M:%S") | \
  272. convert timeformat="%m/%d/%Y %H:%M:%S" mktime(StartTime) | \
  273. eval SessionDuration = tostring(CurrentTime - StartTime, "duration") | \
  274. table "User Name" "Machine Name" "Start Time" SessionDuration "Client Name" "Client Version" "Client Address" "Session Key" "Catalog Name" "Controller" "Desktop Group" "Desktop Kind" "Establishment Duration" "OS Type" "Session Type" | \
  275. rename SessionDuration AS "Session Duration"',
  276. "app": utils.getCurrentApp(),
  277. "auto_cancel": 90,
  278. "preview": true
  279. }, {tokens: true, tokenNamespace: "submitted"});
  280.  
  281. //***********************************
  282. // Post Process Search for Map
  283. //***********************************
  284. var postProcessMap = new PostProcessManager({
  285. "search": 'iplocation "Client Address" | geostats count',
  286. "managerid": "searchUserSession",
  287. "id": "postProcessMap"
  288. }, {tokens: true, tokenNamespace: "submitted"});
  289.  
  290. //***********************************
  291. // Session Processes Search
  292. //***********************************
  293. var searchUserSessionProcess = new SearchManager({
  294. "id": "searchUserSessionProcess",
  295. "cancelOnUnload": true,
  296. "latest_time": "$latest$",
  297. "earliest_time": "$earliest$",
  298. "search": '`xd_perfmon_index` host="$machinename$" sourcetype="PerfmonMk:Process" \
  299. [search `xd_index` sourcetype="xendesktop:*:SessionProcess" host="$machinename$" | multikv | search UserName="$username$" | stats count by ProcessId | fields ProcessId | rename ProcessId AS ID_Process] | \
  300. rename IO_Write_Operations/sec AS iowrite | rename IO_Read_Operations/sec AS ioread | \
  301. eval iops = iowrite + ioread | \
  302. stats count by _time instance %_Processor_Time Working_Set_-_Private iops ioread iowrite'
  303. }, {tokens: true, tokenNamespace: "submitted"});
  304.  
  305.  
  306. //***********************************
  307. // Processor Time Chart
  308. //***********************************
  309. var postProcessUserSessionProcessCpu = new PostProcessManager({
  310. "search": 'timechart avg(%_Processor_Time) AS "Avg. % Processor Time" BY instance',
  311. "managerid": "searchUserSessionProcess",
  312. "id": "postProcessUserSessionCpu"
  313. }, {tokens: true, tokenNamespace: "submitted"});
  314.  
  315. var chartCpu = new ChartElement({
  316. "id": "chartCpu",
  317. "charting.chart": "line",
  318. "charting.drilldown": "all",
  319. "charting.layout.splitSeries": "0",
  320. "charting.chart.style": "minimal",
  321. "resizable": true,
  322. "charting.axisY.scale": "linear",
  323. "charting.legend.labelStyle.overflowMode": "ellipsisMiddle",
  324. "charting.legend.placement": "bottom",
  325. "charting.axisTitleX.visibility": "collapsed",
  326. "charting.axisX.sliceCollapsingThreshold": "0.01",
  327. "charting.axisY.maximumNumber": "100",
  328. "charting.chart.minimumNumber": "0",
  329. "charting.axisX.scale": "linear",
  330. "charting.chart.stackMode": "default",
  331. "charting.axisTitleY.visibility": "visible",
  332. "charting.chart.nullValueMode": "zero",
  333. "managerid": "postProcessUserSessionCpu",
  334. "el": $('#chartCpu')
  335. }, {tokens: true}).render();
  336.  
  337. //***********************************
  338. // Memory Chart
  339. //***********************************
  340. var postProcessUserSessionProcessMem = new PostProcessManager({
  341. "search": 'timechart avg(Working_Set_-_Private) AS "Avg. Memory" BY instance',
  342. "managerid": "searchUserSessionProcess",
  343. "id": "postProcessUserSessionMem"
  344. }, {tokens: true, tokenNamespace: "submitted"});
  345.  
  346. var chartMem = new ChartElement({
  347. "id": "chartMem",
  348. "charting.chart": "line",
  349. "charting.drilldown": "all",
  350. "charting.layout.splitSeries": "0",
  351. "charting.chart.style": "minimal",
  352. "resizable": true,
  353. "charting.axisY.scale": "linear",
  354. "charting.legend.labelStyle.overflowMode": "ellipsisMiddle",
  355. "charting.legend.placement": "bottom",
  356. "charting.axisTitleX.visibility": "collapsed",
  357. "charting.chart.sliceCollapsingThreshold": "0.01",
  358. "charting.axisX.scale": "linear",
  359. "charting.chart.stackMode": "default",
  360. "charting.axisTitleY.visibility": "visible",
  361. "charting.chart.nullValueMode": "zero",
  362. "managerid": "postProcessUserSessionMem",
  363. "el": $('#chartMem')
  364. }, {tokens: true}).render();
  365.  
  366. //***********************************
  367. // IOPS Chart
  368. //***********************************
  369. var postProcessUserSessionProcessIops = new PostProcessManager({
  370. "search": 'timechart avg(iops) AS "Avg. IOPS" by instance',
  371. "managerid": "searchUserSessionProcess",
  372. "id": "postProcessUserSessionIops"
  373. }, {tokens: true, tokenNamespace: "submitted"});
  374.  
  375. var chartIops = new ChartElement({
  376. "id": "chartIops",
  377. "charting.chart": "line",
  378. "charting.drilldown": "all",
  379. "charting.layout.splitSeries": "0",
  380. "charting.chart.style": "minimal",
  381. "resizable": true,
  382. "charting.axisY.scale": "linear",
  383. "charting.legend.labelStyle.overflowMode": "ellipsisMiddle",
  384. "charting.legend.placement": "bottom",
  385. "charting.axisTitleX.visibility": "collapsed",
  386. "charting.chart.sliceCollapsingThreshold": "0.01",
  387. "charting.axisX.scale": "linear",
  388. "charting.chart.stackMode": "default",
  389. "charting.axisTitleY.visibility": "visible",
  390. "charting.chart.nullValueMode": "zero",
  391. "managerid": "postProcessUserSessionIops",
  392. "el": $('#chartIops')
  393. }, {tokens: true}).render();
  394.  
  395. //***********************************
  396. // Process Details Table
  397. //***********************************
  398. var postProcessUserSessionProcessDetail = new PostProcessManager({
  399. "search": 'stats avg(%_Processor_Time) AS "Avg. % Processor Time" avg(Working_Set_-_Private) AS "Avg. Memory" avg(iops) AS "Avg. IOPS" avg(ioread) AS "Avg. Read IO" avg(iowrite) AS "Avg. Write IO" BY instance',
  400. "managerid": "searchUserSessionProcess",
  401. "id": "postProcessUserSessionDetail"
  402. }, {tokens: true, tokenNamespace: "submitted"});
  403.  
  404. var tableProcesses = new TableElement({
  405. "id": "tableProcesses",
  406. "displayRowNumbers": false,
  407. "managerid": "postProcessUserSessionDetail",
  408. "el": $('#table-user-processes')
  409. }, {tokens: true}).render();
  410.  
  411.  
  412. //***********************************
  413. // DataView - pivots the table
  414. //***********************************
  415. new DataView({
  416. id: "session-details",
  417. managerid: "searchUserSession",
  418. template: $('#user-session-template').html(),
  419. el: $('#user-session-details')
  420. }, {tokens: true}).render();
  421.  
  422. //***********************************
  423. // Map Element
  424. //***********************************
  425. new MapElement({
  426. "id": "map",
  427. "resizable": true,
  428. "height": "200px",
  429. "managerid": "postProcessMap",
  430. "mapping.tileLayer.url": "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
  431. "mapping.tileLayer.subdomains": "[a,b,c]",
  432. "mapping.tileLayer.minZoom": 0,
  433. "mapping.tileLayer.maxZoom": 18,
  434. "mapping.tileLayer.attribution": "Map data (c) 2012 OpenStreetMap contributors, CC-BY-SA.",
  435. "el": $('#map-login')
  436. }, {tokens: true}).render();
  437.  
  438. postProcessMap.on("search:done", function(properties) {
  439. if(properties.content.resultCount > 0) {
  440.  
  441. // Show Map
  442. $("#cell-detail").css("width","50%");
  443. $("#cell-map")
  444. .css("visibility", "visible")
  445. .css("width", "50%");
  446. }
  447. });
  448.  
  449. //***********************************
  450. // Splunk Dashboard UI
  451. //***********************************
  452. new HeaderView({
  453. id: 'header',
  454. section: 'dashboards',
  455. el: $('.header'),
  456. acceleratedAppNav: true
  457. }, {tokens: true}).render();
  458.  
  459. new FooterView({
  460. id: 'footer',
  461. el: $('.footer')
  462. }, {tokens: true}).render();
  463.  
  464. new Dashboard({
  465. id: 'dashboard',
  466. el: $('.dashboard-body')
  467. }, {tokens: true}).render();
  468.  
  469.  
  470.  
  471. //****************************************
  472. // Form Inputs
  473. //****************************************
  474. var field1 = new TimeRangeInput({
  475. "id": "field1",
  476. "preset": "Last 24 hours",
  477. "earliest_time": "$earliest$",
  478. "latest_time": "$latest$",
  479. "el": $('#field1')
  480. }, {tokens: true}).render();
  481.  
  482. var field2 = new TextInput({
  483. "id": "field2",
  484. "value": "$form.username$",
  485. "el": $('#field2')
  486. }, {tokens: true}).render();
  487.  
  488. field2.on("change", function(value, input, options) {
  489. if (!field2.hasValue()) {
  490. defaultUpdate['field2'] = true;
  491. this.val(field2.settings.get("default"));
  492. return;
  493. }
  494.  
  495. var newValue = field2.val() || field2.settings.get("default");
  496. var newComputedValue = newValue;
  497.  
  498. // Update computed value
  499. defaultTokenModel.set("username", newComputedValue);
  500. });
  501. defaultUpdate['field2'] = true;
  502. field2.trigger("change", field2.val(), field2);
  503.  
  504. var field3 = new TextInput({
  505. "id": "field3",
  506. "value": "$form.machinename$",
  507. "el": $('#field3')
  508. }, {tokens: true}).render();
  509.  
  510. field3.on("change", function(value, input, options) {
  511. if (!field3.hasValue()) {
  512. defaultUpdate['field3'] = true;
  513. this.val(field3.settings.get("default"));
  514. return;
  515. }
  516.  
  517. var newValue = field3.val() || field3.settings.get("default");
  518. var newComputedValue = newValue;
  519.  
  520. // Update computed value
  521. defaultTokenModel.set("machinename", newComputedValue);
  522. });
  523. defaultUpdate['field3'] = true;
  524. field3.trigger("change", field3.val(), field3);
  525.  
  526. //
  527. // Handle form submit
  528. //
  529. var submit = new SubmitButton({
  530. id: 'submit',
  531. el: $('#search_btn')
  532. }, {tokens: true}).render();
  533.  
  534. submit.on("submit", function() {
  535. submitTokens();
  536. });
  537.  
  538. //
  539. // Submit any form data
  540. //
  541. if (!_.isEmpty(urlTokenModel.toJSON())){
  542. submitTokens();
  543. }
  544.  
  545. //
  546. // Signal the dashboard is done loading.
  547. //
  548. DashboardController.ready();
  549. pageLoading = false;
  550. }
  551. );
  552. </script>
  553. </body>
  554. </html>
RAW Paste Data