Browse Source

Ladeampel der Uni Köln #4

master
Daniel Quathamer 3 weeks ago
parent
commit
d84edf477f
  1. 164
      module/etl/ladejobs.jsp
  2. 49
      module/etl/laderoutine/laderoutine.awk
  3. 31
      module/etl/laderoutine/laderoutine.sh
  4. 40
      module/etl/portlet.sql
  5. 34
      module/etl/readme.md

164
module/etl/ladejobs.jsp

@ -0,0 +1,164 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.io.BufferedReader, java.io.InputStreamReader, java.io.IOException, java.io.StringWriter, java.io.PrintWriter" %>
<html>
<head>
<title>Ladejobs</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0; /* Ensure no extra margin */
padding: 0; /* Ensure no extra padding */
overflow: visible; /* Ensure content is fully visible */
}
table {
width: 100%; /* Ensure table takes full width */
border-collapse: collapse;
font-size: small;
}
table, th, td {
border: 1px solid black;
}
th, td {
padding: 7px;
text-align: left;
white-space: normal;
}
th {
background-color: #f2f2f2;
}
td {
background-color: white;
}
.container {
display: flex;
flex-direction: row; /* Align items vertically */
align-items: flex-start;
width: 100%; /* Ensure container takes full width */
height: 100%; /* Ensure container takes full height */
overflow: visible; /* Ensure content is fully visible */
}
.traffic-light-container {
margin-top: 10px;
margin-left: 20px; /* Adjust the margin as needed */
}
.traffic-light {
width: 40px; /* Reduced width */
background-color: #333;
padding: 10px; /* Reduced padding */
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.light {
width: 30px; /* Reduced width */
height: 30px; /* Reduced height */
margin: 5px 0; /* Reduced margin */
border-radius: 50%;
background-color: #555;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.light.red {
background-color: rgb(70, 0, 0);
}
.light.red.on {
background-color: red;
box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
}
.light.yellow {
background-color: rgb(70, 70, 0);
}
.light.yellow.on {
background-color: yellow;
box-shadow: 0 0 10px rgba(255, 255, 0, 0.5);
}
.light.green {
background-color: rgb(0, 70, 0);
}
.light.green.on {
background-color: rgb(0, 255, 0);
box-shadow: 0 0 10px rgba(0, 255, 0, 0.5);
}
</style>
</head>
<body>
<div class="container">
<div>
<%
boolean allSuccess = true;
boolean anyRunning = false;
try {
Runtime runtime = Runtime.getRuntime();
// Execute the system command
String[] commands = {"/bin/sh", "-c", "cd ~/alex_skripte/laderoutine && laderoutine.sh"};
Process process = runtime.exec(commands);
// Read the output of the command
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
// Start HTML table
out.println("<table>");
out.println("<tr><th>Modul</th><th>Start</th><th>Ende</th><th>Status</th></tr>");
// Process each line and add to the table
while ((line = reader.readLine()) != null) {
// Split the line into columns
String[] columns = line.split("\\t");
out.println("<tr>");
for (String column : columns) {
out.println("<td>" + column + "</td>");
}
out.println("</tr>");
// Check the status column (assuming it's the fourth column)
String status = columns[3].trim();
if (status.equals("Fehler")) {
allSuccess = false;
} else if (status.equals("läuft gerade...")) {
anyRunning = true;
}
}
// End HTML table
out.println("</table>");
// Read the error stream of the command
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((line = errorReader.readLine()) != null) {
out.println("ERROR: " + line);
}
// Wait for the command to complete
int exitCode = process.waitFor();
// out.println("<p>Exited with code: " + exitCode + "</p>");
} catch (IOException | InterruptedException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
out.println("Error: " + sw.toString());
}
%>
</div>
<div class="traffic-light-container">
<div class="traffic-light">
<div class="light red <% if (!allSuccess) { %>on<% } %>"></div>
<div class="light yellow <% if (anyRunning && allSuccess) { %>on<% } %>"></div>
<div class="light green <% if (allSuccess && !anyRunning) { %>on<% } %>"></div>
</div>
</div>
</div>
</body>
</html>

49
module/etl/laderoutine/laderoutine.awk

@ -0,0 +1,49 @@
BEGIN {
row = 1;
log_beginn = 0
}
function eof() {
rows[row++] = sprintf("%-10s\t%-20s\t%-20s\t%-10s\t",modul, start, ende, status)
}
/^-- Start [A-Z][^a-z]/ {
if (log_beginn != 0) {
ende = ""
eof()
}
log_beginn = 1;
modul = $3;
start = $6" "$7;
next
}
/^Aktion / {
status = "läuft gerade..."
next
}
/(^Ein Fehler ist aufgetreten|^Es ist ein Fehler aufgetreten)/ {
status = "Fehler";
next
}
/^-- Ende [A-Z][^a-z]/ {
ende = $6" "$7;
if (status !~ /Fehler/) {
status = "Erfolg"
}
eof();
log_beginn = 0;
next
}
END {
if (log_beginn != 0) {
ende = ""
eof()
}
for (i = 1; i <= row - 1; i++) {
print rows[i]
}
}

31
module/etl/laderoutine/laderoutine.sh

@ -0,0 +1,31 @@
#!/usr/bin/bash
ERFOLG_LOG=/home/superx/db/module/erfolg/L_ERFOLG_update.log
GANG_LOG=/home/superx/db/module/gang/L_GANG_update.log
ZUL_LOG=/home/superx/db/module/zul/L_ZUL_update.log
QA_LOG=/home/superx/db/module/qa/L_QA_update.log
SOS_LOG=/home/superx/db/module/sos/L_SOS_update.log
COSTAGE_LOG=/home/superx/db/module/costage/L_COSTAGE_update.log
logs=""
if [ -f $ERFOLG_LOG ]; then
logs="$logs $ERFOLG_LOG"
fi
if [ -f $GANG_LOG ]; then
logs="$logs $GANG_LOG"
fi
if [ -f $ZUL_LOG ]; then
logs="$logs $ZUL_LOG"
fi
if [ -f $QA_LOG ]; then
logs="$logs $QA_LOG"
fi
if [ -f $SOS_LOG ]; then
logs="$logs $SOS_LOG"
fi
if [ -f $COSTAGE_LOG ]; then
logs="$logs $COSTAGE_LOG"
fi
awk -f laderoutine.awk $logs | sort -r -b -k 2.7,2.10 -k 2.4,2.5 -k 2.1,2.2 -k 3.1,3.2 -k 3.4,3.5 -k 3.7,3.8

40
module/etl/portlet.sql

@ -0,0 +1,40 @@
INSERT INTO sx_portlet
(
name,
TYPE,
class,
icon,
content,
sortnr_initial,
visible,
gueltig_von,
gueltig_bis
)
VALUES
(
'Status Ladejobs',
'HTML',
'green',
'icon-tasks',
'<iframe id="ladejobs_iframe"src="/superx/ladejobs.jsp" style="width: 100%; border: none;" onload="resizeIframe(this)" scrolling="no"></iframe>
<script>
function resizeIframe(iframe) {
iframe.style.height = iframe.contentWindow.document.documentElement.scrollHeight + ''px'';
}
window.setInterval(function() {
reloadIFrame()
}, 60000);
function reloadIFrame() {
console.log(''reloading..'');
document.getElementById(''ladejobs_iframe'').contentWindow.location.reload();
}
</script>
<p style="font-size: xx-small; margin-top: 2px; margin-bottom: 3px;">Automatische Aktuallisierung alle 60s</p>',
NULL,
'all',
DATE '1900-01-01',
DATE '3000-01-01'
);

34
module/etl/readme.md

@ -0,0 +1,34 @@
# Ladeampel
**Beschreibung**
Die Ladeampel kann in einem SuperX-Portlet eingebunden werden. Sie zeigt den Status der Laderoutinen der einzelnen Module. Dabei werden drei Zustände unterschieden:
- **Erfolg**: Die Laderoutine ist erfolgreich durchgelaufen
- **läuft gerade**: Die Laderoutine wird gerade ausgeführt
- **Fehler:**: Die Laderoutine ist mit einem Fehler beendet worden
## Installation
Die Ladeampel besteht aus vier Komponenten:
- **laderoutine.awk**: AWK-Programm, welches die Logfiles der Module einliest und den Status für jedes Modul ermittelt.
- **laderoutine.sh**: Bash-Skript, welches die Pfade zu den Logfiles der einzelnen Module enthält. Es ruft das AWL-Programm auf.
- **ladejobs.jsp**: Java Server Page, welche das Bash-Skript aufruft und für den Status eine Ampel und eine Tabelle mit dem Status aller Module ausgibt.
- **portlet.sql**: Enthält SQL-Insert-Statement zum Anlegen des Portlets in SuperX. Das Portlet enthält ein iFrame, welches die Java Server Page einbindet. Durch JavaScript wird das iFrame alle 60 Sekunden neu geladen, damit sich der Status aktuallisiert.
Die Installation erfolgt in folgenden Schritten:
1. Der Ordner *laderoutine* enthält das AWK-Programm und das Bash-Skript. Er kann z.B. im Home-Verzeichnis vom Linux-User *superx* abgelegt werden.
2. Die JSP-Datei muss in den Ordner `/home/superx/webserver/tomcat/webapps/superx/`.
3. In der JSP-Datei muss dann in Zeile 106 der Pfad zum Bash-Skript angepasst werden.
4. Zuletzt muss die SQL-Datei ausgeführt werden, um das Portlet anzulegen.
5. **Optional** Die Reihenfolge der Portlets wird über die tid der Tabelle `sx_portlet` bestimmt und lässt sich anpassen, um die Portlets umzusortieren, falls noch weitere Portlets vorhanden sind.
## Verwendung
Die Ampel sollte nun auf der Startseite von SuperX sichtbar sein. Alle 60 Sekunden wird die Ampel aktuallisiert, um den aktuellen Status anzuzeigen.
## Kontakt
- **Autor**: Alexander Bien (Universität zu Köln)
- **E-Mail**: a.bien@uni-koeln.de
Loading…
Cancel
Save