6 #include <QCoreApplication>
37 , _adminEmail(adminEmail)
39 , cp_warn(YELLOW, BOLD)
74 if (r->
_path ==
"settings")
92 if (r->
_path ==
"settings")
96 QDateTime now = QDateTime::currentDateTime();
98 QJsonObject o = r->
_data.object();
100 if (o.contains(
"adminemail"))
101 { QString e = o[
"adminemail"].toString();
105 m[
"data"] = QString(
"%1,LOG,%2,%3,Set admin email to '%4'\n").arg(now.toMSecsSinceEpoch()).arg(r->
_user).arg(
_logLevel).arg(e);
112 if (o.contains(
"logtime"))
113 {
int l = qBound(0,o[
"logtime"].toInt(),4);
117 m[
"data"] = QString(
"%1,LOG,%2,%3,Set log time format to %4\n").arg(now.toMSecsSinceEpoch()).arg(r->
_user).arg(
_logLevel).arg(l);
124 if (o.contains(
"loglevel"))
125 {
int l = qBound(0,o[
"loglevel"].toInt(),9);
129 m[
"data"] = QString(
"%1,LOG,%2,%3,Set log level to %4\n").arg(now.toMSecsSinceEpoch()).arg(r->
_user).arg(
_logLevel).arg(l);
200 QJsonDocument diffdoc = t->
_data;
201 QString
diff = diffdoc.object()[
"data"].toString();
203 QString time =
diff.section(
",",0,0);
204 QByteArray which =
diff.section(
",",1,1).toUtf8();
206 QByteArray level =
diff.section(
",",3,3).toUtf8();
207 QByteArray message =
diff.section(
",",4).toUtf8();
209 int ll = qBound(0,level.toInt(),9);
215 std::string timeString =
"";
216 std::string timeOffset =
"";
218 QDateTime now = QDateTime::fromMSecsSinceEpoch( time.toLongLong() );
221 case 0: timeString =
"";
break;
222 case 1: timeString = now.toString(
"hh:mm:ss.zzz ").toStdString();
break;
223 case 2: timeString = now.toString(
"yyyy/MM/dd hh:mm:ss:zzz t ").toStdString();
break;
224 case 3: timeString = now.toString(
"yyyy/MM/dd hh:mm:ss:zzz ").toStdString();
226 int offh = qFloor(now.offsetFromUtc()/(60.0*60.0));
227 int offm = qFloor(now.offsetFromUtc()/(60.0)) % 60;
228 timeOffset = QString(
"%1%2:%3 GMT ").arg(offh >= 0 ?
"+" :
"").arg(offh).arg(offm,2,10,QChar(
'0')).toStdString();
233 timeString = time.toStdString()+
" ";
238 std::cout <<
cp_bold.cp_s_init() << timeString << timeOffset <<
"[ LOG " << level.data() <<
" ] " << qUtf8Printable(t->
_user) <<
" " <<
cp_bold.cp_s_rst() << message.data();
240 std::cout <<
cp_warn.cp_s_init() << timeString << timeOffset <<
"[ WARN " << level.data() <<
" ] " << qUtf8Printable(t->
_user) <<
" " << message.data() <<
cp_warn.cp_s_rst();
242 std::cerr <<
cp_error.cp_s_init() << timeString << timeOffset <<
"[ ERROR ] " << qUtf8Printable(t->
_user) <<
" " << message.data() <<
cp_error.cp_s_rst();
245 std::cerr <<
cp_error.cp_s_init() << timeString << timeOffset <<
"[ CRITICAL ] " <<
diff.toUtf8().data() <<
cp_error.cp_s_rst();
247 std::cerr <<
cp_error.cp_s_init() << timeString << timeOffset <<
" notification email sent to: " << qUtf8Printable(
_adminEmail) << std::endl <<
cp_error.cp_s_rst();
251 std::cerr <<
cp_error.cp_s_init() << timeString << timeOffset <<
"[ UNKNOWN (" << which.data() <<
") ] " << qUtf8Printable(t->
_user) <<
cp_error.cp_s_rst() <<
" " << diffdoc.toJson().data() << (
diff.right(1)!=
"\n"?
"\n" :
"");
253 std::cout << std::flush;
254 std::cerr << std::flush;
273 address = address.replace(
"'",
"\"'\"").trimmed();
274 subject = subject.replace(
"'",
"\"'\"").trimmed();
275 message = message.replace(
"'",
"\"'\"").trimmed();
278 {
VFS::ERROR(
"Cannot send CRITICAL email when address is empty. Provide a space-separated list of adminemail addresses in the root VFS env config.\n");
283 QString command = QString(
"mail -s '%1' '%2' <<< '%3'").arg(subject).arg(address).arg(message);
284 printf(
"%s\n",qUtf8Printable(command));
287 int s = system(qUtf8Printable(command));
289 VFS::ERROR( QString(
"Could not send email with command:\n%1").arg(command));
int _logLevel
Filter log entries by this value... lower entries are very important, higher ones are more fine-grain...
int _logTime
Include log entry time, where 0 = none, 1 = locale time, 2 = locale time and date,...
virtual void submit(VFS_request *r)
Submit settings to this logger.
virtual VFS_node * find(VFS_request *r)
This method will return this if the path is settings, otherwise VFS_node::find().
VFS_node * _critical
Crash may be imminent, the administrator address will be emailed this message if it is possible.
ColorPrint cp_warn
Color settings for warning messages.
VFS_node * _warnings
Warning logs, which provide non-critical information.
ColorPrint cp_error
Color settings for error messages.
VFS_node * _log
Message collector node, which subscribes to the other nodes as an aggregator.
ColorPrint cp_bold
Color settings for bold printing.
virtual void applyDiff(VFS_request *t)
Receive log information from a logging mechanism.
void email(QString address, QString subject, QString message)
Email an administrator about a problem.
QString _adminEmail
For CRITICAL() messages, this is the address that will be emailed.
VFS_node * _messages
A message logging node.
VFS_node * _errors
Error logs, which mean there is a problem but not a crash.
Q_INVOKABLE VFS_logger(int logLevel, int logTime, QString adminAddress)
VFS_logger constructor.
VFS_node is the base class from which all other VFS_node classes derive.
virtual VFS_node * append(QString name, VFS_node *node, bool containerCheck=true, QString user="server")
Append a VFS_node as a child of this node.
virtual VFS_request * createRequest(VFS_request::requestType type, QString path, QString user="unknown", QJsonDocument data=QJsonDocument(), QJsonObject metadata=QJsonObject(), bool dontDelete=false)
Create a new VFS_request with this object as _origin.
virtual void issueRequest(VFS_request *t)
A convenience function.
VFS_node * find(QString path)
Find a node by string path.
void diff(VFS_node *origin, VFS_request *t)
Emit a diff, which will trigger notifySubscribers() for a mounted node.
virtual void applyDiff(VFS_request *r)
Apply a diff received via subscription.
The base class for all requests between nodes.
@ subscribe
subscribe to a path (9)
VFS_node * _origin
the origin of the request
QString _user
who initiated this request, mostly for logging
QString _reason
if something (probably bad) happened, this is the reason
QString _path
the target path remnant... the remaining path element once the request has found its target
bool _success
if the request was successfully completed
QJsonDocument _data
the request payload
VFS_stream stores data sequentially within a buffer.
static void ERROR(QString message, int level=0, QString user="server")
Send a message to the VFS::_errors VFS_stream.
message(m)
Change the message of an existing arrowMessage.