Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue249 select error log level #255

Merged
merged 37 commits into from
Jul 5, 2024
Merged

Conversation

ayase-mstk
Copy link
Collaborator

@ayase-mstk ayase-mstk commented Jul 2, 2024

変更点

error_logで出力レベルを変更できるようにしました。
log fdの管理はAccessLog classとErrorLog classでそれぞれ行うようにしました。
writeErrorlogを使用したところで、エラーレベルを引数に追加しました。
test/conf/directive_err_test.shに少しテストを追加しました。
make fcleanでデフォルトエラーログファイルを削除するようにしました。

見ていただきたい点

ErrorLog.hppの設計
utils/syscall_wrapper.cppのエラーログレベルがこれで大丈夫か

Copy link
Owner

@YungTatyu YungTatyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

早速の対応ありがとうございます。

@@ -55,7 +57,7 @@ clean:

fclean: clean
$(MAKE) fclean -C $(TEST_CGI_DIR)
$(RM) $(NAME)
$(RM) $(NAME) $(LOG_FILE)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logやerror fileは削除されないほうがいいんじゃないでしょうか?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

知らぬ間にログがとても増えてしまっても良くないかなと思いこのようにしました。
消すのはあくまでもデフォルトのログなので、残したければ他の名前のログに書き込むようにすれば大丈夫かなとも思いました。

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あくまで、makefileはbuildの自動化ツールなので、ログなどは特に触らないで統一してもいいかもしれません。
それかtestを実行する際に、テストスクリプトでlogを削除することもいいかもしれません
一つの案なので、参考程度に

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一理ありますね。ただ実はログディレクトリはmakefileで作っているので、すでにログに多少触ってはいます。
テストスクリプトでのみ作成されているようなlogはすべて削除するようにしていますが、デフォルトで作られるログはどうするか悩ましいですね。あとで相談させてください。

@@ -36,7 +36,7 @@ void cgi::CgiExecutor::executeCgiScript(const HttpRequest& request, const HttpRe
prepareCgiExecution(request, response, full_path, cgi_sock, cli_sock);
execve(this->script_path_.c_str(), const_cast<char* const*>(this->argv_.data()),
const_cast<char* const*>(this->meta_vars_.data()));
WebServer::writeErrorlog(error::strSysCallError("execve") + "\n");
WebServer::writeErrorlog(error::strSysCallError("execve"), config::WARN);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syscallのエラーは、emerg統一でいいのではないでしょうか
あえて、warnにしましたか?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そうですね、あえて全てEMERGしなかったというのはおっしゃる通りです。
しかしエラーの基準が少し曖昧であることは確かなので、chatgptに聞いてみたところ以下のように出ました。
これによると、一般的にWARN以上が異常動作かもしれません。またemergはサーバーが使用不能になるほどのエラーかなと思っています。なので例えばaccessなどは使いところによってはEMERGだと大袈裟すぎると思っています。
またcgi周りのエラーもサーバーの仕様が続行不可能とまでは言えないかなとも思いました。

それともすべてシステムコールは統一でEMERGのほうがわかりやすいでしょうか?

DEBUG(デバッグ)
概要: 開発中の詳細な情報。通常は問題のトラブルシューティングに役立つ情報。
使用例: 変数の値、関数の呼び出し、ループの中のステップなど。

INFO(情報)
概要: 正常動作の過程を記録するためのメッセージ。
使用例: サービスの開始や停止、設定の読み込みなどのイベント。

NOTICE(通知)
概要: 通常の動作中に注意を要する事象。
使用例: 設定ファイルの非推奨設定の使用、予期しないが致命的ではない事象。

WARNING(警告)
概要: 予期しない動作が発生したが、システムの運用には問題ない事象。
使用例: メモリの使用量が高いが、まだ正常に動作している場合など。

ERROR(エラー)
概要: システムが正常に動作できない事象が発生したが、アプリケーションは続行可能。
使用例: ファイルの読み取り失敗、リソースの不足など。

CRITICAL(重大)
概要: 重大なエラーであり、システムの一部が正常に機能しない。
使用例: データベースの接続失敗、重要なコンポーネントのクラッシュなど。

ALERT(警報)
概要: 速やかに対処が必要な状態。
使用例: アプリケーションのクラッシュ、セキュリティの侵害が発生した場合など。

EMERGENCY(緊急)
概要: システムが使用不可能な状態。
使用例: システム全体の停止、重大なハードウェア障害など。

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNよりはERRORのほうがいいかと思いました。
warnは注意というイメージが強いので

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ではシステムコールは最低でもERRORにしようと思います。

Comment on lines 185 to 186
if (syscall_wrapper::Access(path, F_OK, false) == 0 && syscall_wrapper::Access(path, W_OK, true) == -1) {
std::cerr << error::strSysCallError("access", path) << std::endl;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラー出力するなら、ログに書き込まなくてもいいかと思いました。
この処理はサーバーが立ち上がるまえだと思うので、なおさらエラー出力だけでいいかもです。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一応nginxはbindなどが失敗していたら標準エラー出力とログの両方に書いていたので合わせました。
無くした方がいいでしょうか?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今のままでいいと思います

return syscall_wrapper::Open(log_path, kLogFileFlags, kLogFileMode);
}

bool config::checkFileAccess(const std::string& path) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haveWritePermission()
みたいな命名のほうがわかりやすいかと思いました。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おっしゃる通りですね。修正します。

Comment on lines 564 to 581
case DEBUG:
mask |= DEBUG; // fall through
case INFO:
mask |= INFO; // fall through
case NOTICE:
mask |= NOTICE; // fall through
case WARN:
mask |= WARN; // fall through
case ERROR:
mask |= ERROR; // fall through
case CRIT:
mask |= CRIT; // fall through
case ALERT:
mask |= ALERT; // fall through
case EMERG:
mask |= EMERG; // fall through
default:
break;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

breakがなくても、compileエラーにならないんですね

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultがなくてもcompile通りそうだと思いましたがどうでしょうか

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// fall throghというコメントがあれば、breakしないでそれ以下のcaseに進めるようです。つまり、CRITであれば、CRITとALERTとEMERGのcaseの中の処理がされます。
defaultはなくてもいけそうです。ありがとうございます。

Comment on lines 82 to 103
std::string config::LogLevelToStr(LOG_LEVEL level) {
switch (level) {
case DEBUG:
return "debug";
case INFO:
return "info";
case NOTICE:
return "notice";
case WARN:
return "warn";
case ERROR:
return "error";
case CRIT:
return "crit";
case ALERT:
return "alert";
case EMERG:
return "emerg";
default:
return "unknown";
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error log classのメンバ関数にしたらどうでしょうか

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum LOG_LEVELがconfig namespaceにあるのでこのようにしたのですがErrorLog classにあるほうがいいでしょうか?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrorLog classの方が整理されていると思います。
少なくとも、ErrorLog.hppに書いてあげたらいいと思います。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

かしこまりました。

@@ -64,7 +66,8 @@ int NetworkIOHandler::setupSocket(const std::string& address, unsigned int port)
if (re == -1)
throw std::runtime_error(error::strSysCallError("bind", "to " + address + ":" + utils::toStr(port)));

syscall_wrapper::Listen(listen_fd, SOMAXCONN);
re = syscall_wrapper::Listen(listen_fd, SOMAXCONN);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

例外をスローするときは、mainでキャッチして、改行も出力しています。
なので、改行をつける必要はありません

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラーレベルも出力されないようになっていると思います。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。改行は多分つけてないと思います。
throwするところは以下のように変更しようと思います。

throw std::runtime_error("webserv: [emerg] " + error::strSysCallError("bind", "to " + address + ":" + utils::toStr(port)));

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

socket()のラッパー関数が改行を含んじゃっています。

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listen()も同様です

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。やっと気づきました。(笑)


http {
server {
error_log logs/error.log DEBUG;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このファイルで、ほかのすべてのエラーレベルも一緒にテストしてあげたらいいと思います

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

たぶんconfのエラーは一つのファイルで一つまでしかエラーを検出できないのでエラーレベルの数だけファイルを作ることになるかと思います。

// access_logがコンテキストで指定されていれば出力する
if (location && utils::hasDirective(*location, kAccessLog)) {
for (size_t i = 0; i < location->access_log_list_.size(); i++) {
if (utils::writeChunks(location->access_log_list_[i].getFd(), msg) == -1)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これ全体的にmsgから改行削除しているので、ログに改行がない状態になりませんか?

Copy link
Collaborator Author

@ayase-mstk ayase-mstk Jul 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改行を削除したのはwriteErrorLogだけで、こちらはwriteAccessLogなので大丈夫かと思います。

std::cerr << "webserv: [emerg] realpath() \""
<< "."
<< "\" failed (" << errno << ": " << strerror(errno) << ")" << std::endl;
std::cerr << error::strSysCallError("realpath") << std::endl;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これもエラーレベルの出力が消えてしまっているとおもいます。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。

bool config::haveWritePermission(const std::string& path) {
// ファイルはあるが、write権限がない時ときはerror
if (syscall_wrapper::Access(path, F_OK, false) == 0 && syscall_wrapper::Access(path, W_OK, true) == -1) {
std::cerr << error::strSysCallError("access", path) << std::endl;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これも、エラーレベルの出力が消えてしまっているとおもいます。
error namespaceにエラー出力の関数を作ってしまうのがいいかもしれません。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

printErrorという関数をerror namespaceに追加しました。

Comment on lines 100 to 101
default:
return "unknown";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defautlは削除してもいいと思います。
あとこの関数は、ErrorLog.hppにかいてほしいです

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修正しました。

@@ -96,6 +96,15 @@ class InitLogTest : public ::testing::Test {
delete config_;
}

template <typename T>
int getFdNum(T log_list) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

以下のような命名のほうがいいと思います。
getterは計算量が1

  int countFds(T log_list) {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。

Comment on lines 35 to 36
const int config::ErrorLog::kDefaultLevel_ =
config::WARN | config::ERROR | config::CRIT | config::ALERT | config::EMERG;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これ多分、errorlog.hpp で定義できちゃうと思います。
kTypeと同じように。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

できました!ありがとうございます。
非整数型だけがヘッダー外で定義しないといけないものみたいですね!

@@ -62,9 +64,11 @@ int NetworkIOHandler::setupSocket(const std::string& address, unsigned int port)
// 失敗したとき?
re = syscall_wrapper::Bind(listen_fd, (struct sockaddr*)&servaddr, sizeof(servaddr));
if (re == -1)
throw std::runtime_error(error::strSysCallError("bind", "to " + address + ":" + utils::toStr(port)));
throw std::runtime_error("webserv: [emerg] " +
error::strSysCallError("bind", "to " + address + ":" + utils::toStr(port)));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throwするときに、
webserv [error level]がついてるやつとついていないものが混在しています。
どちらが正解なんでしょうか

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

webserv [error level]
をちゃんとつけてあげるのが正解ぽいです。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

気づきませんでした。ありがとうございます。

@ayase-mstk ayase-mstk merged commit bae1c26 into main Jul 5, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants