kopia lustrzana https://github.com/cyoung/stratux
Developer UI page allows downloading and deleting AHRS logs.
rodzic
e657a400f8
commit
1bf2a9d808
|
@ -795,6 +795,15 @@ func updateStatus() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
globalStatus.Logfile_Size = fileInfo.Size()
|
globalStatus.Logfile_Size = fileInfo.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ahrsLogSize int64
|
||||||
|
ahrsLogFiles, _ := ioutil.ReadDir("/var/log")
|
||||||
|
for _, f := range ahrsLogFiles {
|
||||||
|
if v, _ := filepath.Match("sensors_*.csv", f.Name()); v {
|
||||||
|
ahrsLogSize += f.Size()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalStatus.AHRS_LogFiles_Size = ahrsLogSize
|
||||||
}
|
}
|
||||||
|
|
||||||
type WeatherMessage struct {
|
type WeatherMessage struct {
|
||||||
|
@ -1100,6 +1109,7 @@ type status struct {
|
||||||
UAT_OTHER_total uint32
|
UAT_OTHER_total uint32
|
||||||
Errors []string
|
Errors []string
|
||||||
Logfile_Size int64
|
Logfile_Size int64
|
||||||
|
AHRS_LogFiles_Size int64
|
||||||
BMPConnected bool
|
BMPConnected bool
|
||||||
IMUConnected bool
|
IMUConnected bool
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
"archive/zip"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingMessage struct {
|
type SettingMessage struct {
|
||||||
|
@ -387,10 +389,27 @@ func doReboot() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleDeleteLogFile(w http.ResponseWriter, r *http.Request) {
|
func handleDeleteLogFile(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("handleDeleteLogFile called!!!\n")
|
log.Println("handleDeleteLogFile called!!!")
|
||||||
clearDebugLogFile()
|
clearDebugLogFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleDeleteAHRSLogFiles(w http.ResponseWriter, r *http.Request) {
|
||||||
|
files, err := ioutil.ReadDir("/var/log")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, fmt.Sprintf("error deleting AHRS logs: %s", err), http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var fn string
|
||||||
|
for _, f := range files {
|
||||||
|
fn = f.Name()
|
||||||
|
if v, _ := filepath.Match("sensors_*.csv", fn) ; v {
|
||||||
|
os.Remove("/var/log/" + fn)
|
||||||
|
log.Printf("Deleting AHRS log file %s\n", fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handleDevelModeToggle(w http.ResponseWriter, r *http.Request) {
|
func handleDevelModeToggle(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("handleDevelModeToggle called!!!\n")
|
log.Printf("handleDevelModeToggle called!!!\n")
|
||||||
globalSettings.DeveloperMode = true
|
globalSettings.DeveloperMode = true
|
||||||
|
@ -528,13 +547,63 @@ func delayReboot() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleDownloadLogRequest(w http.ResponseWriter, r *http.Request) {
|
func handleDownloadLogRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "applicaiton/zip")
|
w.Header().Set("Content-Type", "application/zip")
|
||||||
w.Header().Set("Content-Disposition", "attachment; filename='stratux.log'")
|
w.Header().Set("Content-Disposition", "attachment; filename='stratux.log'")
|
||||||
http.ServeFile(w, r, "/var/log/stratux.log")
|
http.ServeFile(w, r, "/var/log/stratux.log")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleDownloadAHRSLogsRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Common error handler
|
||||||
|
httpErr := func(w http.ResponseWriter, e error) {
|
||||||
|
http.Error(w, fmt.Sprintf("error zipping AHRS logs: %s", e), http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := ioutil.ReadDir("/var/log")
|
||||||
|
if err != nil {
|
||||||
|
httpErr(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
z := zip.NewWriter(w)
|
||||||
|
defer z.Close()
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
fn := f.Name()
|
||||||
|
v1, _ := filepath.Match("sensors_*.csv", fn)
|
||||||
|
v2, _ := filepath.Match("stratux.log", fn)
|
||||||
|
if !(v1 || v2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
unzippedFile, err := os.Open("/var/log/" + fn)
|
||||||
|
if err != nil {
|
||||||
|
httpErr(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fh, err := zip.FileInfoHeader(f)
|
||||||
|
if err != nil {
|
||||||
|
httpErr(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
zippedFile, err := z.CreateHeader(fh)
|
||||||
|
if err != nil {
|
||||||
|
httpErr(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(zippedFile, unzippedFile)
|
||||||
|
if err != nil {
|
||||||
|
httpErr(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/zip")
|
||||||
|
w.Header().Set("Content-Disposition", "attachment; filename=\"ahrs_logs.zip\"")
|
||||||
|
}
|
||||||
|
|
||||||
func handleDownloadDBRequest(w http.ResponseWriter, r *http.Request) {
|
func handleDownloadDBRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "applicaiton/zip")
|
w.Header().Set("Content-Type", "application/zip")
|
||||||
w.Header().Set("Content-Disposition", "attachment; filename='stratux.sqlite'")
|
w.Header().Set("Content-Disposition", "attachment; filename='stratux.sqlite'")
|
||||||
http.ServeFile(w, r, "/var/log/stratux.sqlite")
|
http.ServeFile(w, r, "/var/log/stratux.sqlite")
|
||||||
}
|
}
|
||||||
|
@ -747,13 +816,13 @@ func managementInterface() {
|
||||||
http.HandleFunc("/updateUpload", handleUpdatePostRequest)
|
http.HandleFunc("/updateUpload", handleUpdatePostRequest)
|
||||||
http.HandleFunc("/roPartitionRebuild", handleroPartitionRebuild)
|
http.HandleFunc("/roPartitionRebuild", handleroPartitionRebuild)
|
||||||
http.HandleFunc("/develmodetoggle", handleDevelModeToggle)
|
http.HandleFunc("/develmodetoggle", handleDevelModeToggle)
|
||||||
|
|
||||||
http.HandleFunc("/orientAHRS", handleOrientAHRS)
|
http.HandleFunc("/orientAHRS", handleOrientAHRS)
|
||||||
http.HandleFunc("/cageAHRS", handleCageAHRS)
|
http.HandleFunc("/cageAHRS", handleCageAHRS)
|
||||||
http.HandleFunc("/resetGMeter", handleResetGMeter)
|
http.HandleFunc("/resetGMeter", handleResetGMeter)
|
||||||
|
|
||||||
http.HandleFunc("/deletelogfile", handleDeleteLogFile)
|
http.HandleFunc("/deletelogfile", handleDeleteLogFile)
|
||||||
http.HandleFunc("/downloadlog", handleDownloadLogRequest)
|
http.HandleFunc("/downloadlog", handleDownloadLogRequest)
|
||||||
|
http.HandleFunc("/deleteahrslogfiles", handleDeleteAHRSLogFiles)
|
||||||
|
http.HandleFunc("/downloadahrslogs", handleDownloadAHRSLogsRequest)
|
||||||
http.HandleFunc("/downloaddb", handleDownloadDBRequest)
|
http.HandleFunc("/downloaddb", handleDownloadDBRequest)
|
||||||
|
|
||||||
err := http.ListenAndServe(managementAddr, nil)
|
err := http.ListenAndServe(managementAddr, nil)
|
||||||
|
|
|
@ -20,6 +20,8 @@ var URL_AHRS_CAGE = "http://" + URL_HOST_BASE + "/cageAHRS";
|
||||||
var URL_GMETER_RESET = "http://" + URL_HOST_BASE + "/resetGMeter";
|
var URL_GMETER_RESET = "http://" + URL_HOST_BASE + "/resetGMeter";
|
||||||
var URL_DELETELOGFILE = "http://" + URL_HOST_BASE + "/deletelogfile";
|
var URL_DELETELOGFILE = "http://" + URL_HOST_BASE + "/deletelogfile";
|
||||||
var URL_DOWNLOADLOGFILE = "http://" + URL_HOST_BASE + "/downloadlog";
|
var URL_DOWNLOADLOGFILE = "http://" + URL_HOST_BASE + "/downloadlog";
|
||||||
|
var URL_DELETEAHRSLOGFILES = "http://" + URL_HOST_BASE + "/deleteahrslogfiles";
|
||||||
|
var URL_DOWNLOADAHRSLOGFILES = "http://" + URL_HOST_BASE + "/downloadahrslogs";
|
||||||
var URL_DOWNLOADDB = "http://" + URL_HOST_BASE + "/downloaddb";
|
var URL_DOWNLOADDB = "http://" + URL_HOST_BASE + "/downloaddb";
|
||||||
|
|
||||||
// define the module with dependency on mobile-angular-ui
|
// define the module with dependency on mobile-angular-ui
|
||||||
|
@ -91,7 +93,7 @@ app.controller('MainCtrl', function ($scope, $http) {
|
||||||
// any logic global logic
|
// any logic global logic
|
||||||
$http.get(URL_SETTINGS_GET)
|
$http.get(URL_SETTINGS_GET)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
settings = angular.fromJson(response.data);
|
var settings = angular.fromJson(response.data);
|
||||||
$scope.DeveloperMode = settings.DeveloperMode;
|
$scope.DeveloperMode = settings.DeveloperMode;
|
||||||
}, function(response) {
|
}, function(response) {
|
||||||
//Second function handles error
|
//Second function handles error
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel-group col-sm-6">
|
<div class="panel-group col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
@ -8,9 +8,8 @@
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-group reset-flow" align="center">
|
<div class="form-group reset-flow" align="center">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<a ng-click="postRestart()" class=
|
<a ng-click="postRestart()" class="btn btn-primary btn-block"
|
||||||
"btn btn-primary btn-block" style=
|
style="margin-bottom:1em;">Restart Application</a>
|
||||||
"margin-bottom:1em;">Restart Application</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,26 +19,48 @@
|
||||||
<div class="panel-group col-sm-6">
|
<div class="panel-group col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
Logfile (Size: {{Logfile_Size}} bytes)
|
Logfile (Size: {{Logfile_Size}})
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<a href="./downloadlog" ng-click="postDownloadLog()"
|
<a href="./downloadlog" ng-click="postDownloadLog()"
|
||||||
class="btn btn-primary btn-block" style=
|
class="btn btn-primary btn-block"
|
||||||
"margin-bottom:0.5em;">Download Logfile</a>
|
style="margin-bottom:0.5em">Download Logfile</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<a ng-click="postDeleteLog()" class=
|
<a ng-click="postDeleteLog()"
|
||||||
"btn btn-primary btn-block" style=
|
class="btn btn-primary btn-block"
|
||||||
"margin-bottom:0.5em;">Delete Logfile</a>
|
style="margin-bottom:0.5em">Delete Logfile</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-group col-sm-6" style="float:right;">
|
<div class="panel-group col-sm-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
AHRS Log Files (Size: {{AHRS_LogFiles_Size}})
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<a href="./downloadahrslogs" download="ahrs_logs.zip" ng-click="postDownloadAHRSLogs()"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
style="margin-bottom:0.5em">Download AHRS Logs</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<a ng-click="postDeleteAHRSLogs()"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
style="margin-bottom:0.5em">Delete AHRS Logs</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-group col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
Database
|
Database
|
||||||
|
@ -47,13 +68,11 @@
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
|
|
||||||
<a href="./downloaddb" ng-click="postDownloadDB()"
|
<a href="./downloaddb" ng-click="postDownloadDB()"
|
||||||
class="btn btn-primary btn-block" style=
|
class="btn btn-primary btn-block"
|
||||||
"margin-bottom:0.5em;">Download Database</a>
|
style="margin-bottom:0.5em;">Download Database</a>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@ function DeveloperCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
return; // we are getting called once after clicking away from the status page
|
return; // we are getting called once after clicking away from the status page
|
||||||
|
|
||||||
if (($scope.socket === undefined) || ($scope.socket === null)) {
|
if (($scope.socket === undefined) || ($scope.socket === null)) {
|
||||||
socket = new WebSocket(URL_STATUS_WS);
|
var socket = new WebSocket(URL_STATUS_WS);
|
||||||
$scope.socket = socket; // store socket in scope for enter/exit usage
|
$scope.socket = socket; // store socket in scope for enter/exit usage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ function DeveloperCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onmessage = function (msg) {
|
socket.onmessage = function (msg) {
|
||||||
console.log('Received status update.')
|
console.log('Received status update.');
|
||||||
|
|
||||||
var status = JSON.parse(msg.data)
|
var status = JSON.parse(msg.data);
|
||||||
// Update Status
|
// Update Status
|
||||||
$scope.Version = status.Version;
|
$scope.Version = status.Version;
|
||||||
$scope.Build = status.Build.substr(0, 10);
|
$scope.Build = status.Build.substr(0, 10);
|
||||||
|
@ -62,7 +62,8 @@ function DeveloperCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
$scope.UAT_PIREP_total = status.UAT_PIREP_total;
|
$scope.UAT_PIREP_total = status.UAT_PIREP_total;
|
||||||
$scope.UAT_NOTAM_total = status.UAT_NOTAM_total;
|
$scope.UAT_NOTAM_total = status.UAT_NOTAM_total;
|
||||||
$scope.UAT_OTHER_total = status.UAT_OTHER_total;
|
$scope.UAT_OTHER_total = status.UAT_OTHER_total;
|
||||||
$scope.Logfile_Size = status.Logfile_Size;
|
$scope.Logfile_Size = humanFileSize(status.Logfile_Size);
|
||||||
|
$scope.AHRS_LogFiles_Size = humanFileSize(status.AHRS_LogFiles_Size);
|
||||||
// Errors array.
|
// Errors array.
|
||||||
if (status.Errors.length > 0) {
|
if (status.Errors.length > 0) {
|
||||||
$scope.visible_errors = true;
|
$scope.visible_errors = true;
|
||||||
|
@ -70,7 +71,7 @@ function DeveloperCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var uptime = status.Uptime;
|
var uptime = status.Uptime;
|
||||||
if (uptime != undefined) {
|
if (uptime !== undefined) {
|
||||||
var up_d = parseInt((uptime/1000) / 86400),
|
var up_d = parseInt((uptime/1000) / 86400),
|
||||||
up_h = parseInt((uptime/1000 - 86400*up_d) / 3600),
|
up_h = parseInt((uptime/1000 - 86400*up_d) / 3600),
|
||||||
up_m = parseInt((uptime/1000 - 86400*up_d - 3600*up_h) / 60),
|
up_m = parseInt((uptime/1000 - 86400*up_d - 3600*up_h) / 60),
|
||||||
|
@ -80,7 +81,7 @@ function DeveloperCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
// $('#Uptime').text('unavailable');
|
// $('#Uptime').text('unavailable');
|
||||||
}
|
}
|
||||||
var boardtemp = status.CPUTemp;
|
var boardtemp = status.CPUTemp;
|
||||||
if (boardtemp != undefined) {
|
if (boardtemp !== undefined) {
|
||||||
/* boardtemp is celcius to tenths */
|
/* boardtemp is celcius to tenths */
|
||||||
$scope.CPUTemp = String(boardtemp.toFixed(1) + 'C / ' + ((boardtemp * 9 / 5) + 32.0).toFixed(1) + 'F');
|
$scope.CPUTemp = String(boardtemp.toFixed(1) + 'C / ' + ((boardtemp * 9 / 5) + 32.0).toFixed(1) + 'F');
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,6 +126,26 @@ function DeveloperCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.postDeleteAHRSLogs = function () {
|
||||||
|
$http.post(URL_DELETEAHRSLOGFILES).
|
||||||
|
then(function (response) {
|
||||||
|
// do nothing
|
||||||
|
// $scope.$apply();
|
||||||
|
}, function (response) {
|
||||||
|
// do nothing
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.postDownloadAHRSLogs = function () {
|
||||||
|
$http.post(URL_DOWNLOADAHRSLOGFILES).
|
||||||
|
then(function (response) {
|
||||||
|
// do nothing
|
||||||
|
// $scope.$apply();
|
||||||
|
}, function (response) {
|
||||||
|
// do nothing
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
$scope.postDownloadDB = function () {
|
$scope.postDownloadDB = function () {
|
||||||
$http.post(URL_DOWNLOADDB).
|
$http.post(URL_DOWNLOADDB).
|
||||||
then(function (response) {
|
then(function (response) {
|
||||||
|
@ -137,4 +158,13 @@ function DeveloperCtrl($rootScope, $scope, $state, $http, $interval) {
|
||||||
|
|
||||||
connect($scope); // connect - opens a socket and listens for messages
|
connect($scope); // connect - opens a socket and listens for messages
|
||||||
|
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function humanFileSize(size) {
|
||||||
|
if (size === 0) {
|
||||||
|
return '0 B'
|
||||||
|
} else {
|
||||||
|
var i = Math.floor(Math.log(size) / Math.log(1024));
|
||||||
|
return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue