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

logger のロケーションプレフィックス対応 #21

Open
ban-nobuhiro opened this issue Jan 5, 2023 · 10 comments
Open

logger のロケーションプレフィックス対応 #21

ban-nobuhiro opened this issue Jan 5, 2023 · 10 comments
Assignees

Comments

@ban-nobuhiro
Copy link
Contributor

jogasaki docs/logging_policy.md#ロケーションプレフィックス の更新に対応する

@ban-nobuhiro ban-nobuhiro self-assigned this Jan 5, 2023
@ban-nobuhiro
Copy link
Contributor Author

ban-nobuhiro commented Jan 5, 2023

location-prefix ブランチで対応

追記:
便利リンク

@ban-nobuhiro
Copy link
Contributor Author

テストがない

@ban-nobuhiro
Copy link
Contributor Author

テストを追加したが、一方で
コンパイル時計算を強制できておらず、実行時に文字列加工処理が動く
という問題が見つかった。意義の半分ぐらいを喪失している。

C++20 なら consteval で強制できるが、C++17 の範囲内で実現するために
constexpr テンポラリ変数(何らかの gensym で名前付け)に 一度代入してから LOG 等に渡すという方針で行くことにする。
テンポラリ変数を スコープに閉じ込めたいが LOG(LEVEL) << "message" 的な文法を維持したうえでの実現が難しい。

@t-horikawa
Copy link
Contributor

https://github.com/project-tsurugi/tateyama/blob/master/src/tateyama/endpoint/common/logging_helper.h
で使わせて頂いています。改善が完了したら取り込みます。
(可能なら)LOG_LP(x)等はそのまま使えるような改善であればありがたい。

@ban-nobuhiro
Copy link
Contributor Author

対応したのですが、
(利用者が)単文のつもりで書いていても、複文にされてしまう
という副作用ができてしまいました。

@ban-nobuhiro
Copy link
Contributor Author

古典的には C マクロで複文に展開するには do-while{0} を使うが

MACRO(x) << something;

の文法には対応できない。
苦肉の策で以下を思いついた。

#define MACRO(x) if (init; false) {} else stmt

@ban-nobuhiro
Copy link
Contributor Author

以下のような使い方をすると、ぶら下がりelse 警告が出るようになるが、実装上の制限事項としたい。

if (cond) LOG_LP(x) << "message";

workaround は { } で囲むこと

if (cond) { LOG_LP(x) << "message"; }

正確に言うと、ぶら下がりelseの解釈が違う実装では意図通りに動かない可能性があるが、試した処理系すべてで if(c0) if(c1) s1; else s2;if(c0) {if(c1) s1; else s2;} と処理された。(期待通り)

@ban-nobuhiro
Copy link
Contributor Author

公開 api include の logging.h 中に足していたのを、新ファイルとして独立して src 下に移動した。
名前は teyama/endpoint/common/logging_helper.h に倣って logging_helper とした。

あと、先述した ぶらさがり else の挙動(内側の if につく)は、実装依存ではなく、仕様のようだ。
https://en.cppreference.com/w/cpp/language/if

@ban-nobuhiro
Copy link
Contributor Author

operator オーバーロード 関数や lambda 対応したバージョンは作成中だが、
g++ のバグを踏んだり とか、いろいろ面倒そうなので、
取り急ぎ今のバージョンまでを mainline にマージする。

@ban-nobuhiro
Copy link
Contributor Author

operator オーバーロード と キャスト と lambda 対応をした ver.2 を(数日前に) push した。
今までのものは、__PRETTY_FUNCTION__ 文字列の解析に失敗した場合、__FUNCTION__ にフォールバックしていたが、 ver.2 ではコンパイルエラーになる。
そのため、安定を確認するまで旧コードは残しておく。
(コンパイラのバージョンが変わって __PRETTY_FUNCTION__ の構成が変わった場合などにも起こりうる。一応 g++-9, g++-10, g++-11, clang++-11 に対応したつもり)

ドキュメント:
https://github.com/project-tsurugi/limestone/blob/location-prefix/docs/location-prefix_ja.md

懸念点:
clang-tidy が LOG_LP(x) 等の行で bugprone-exception-escape の警告を出すようになってしまった。
constexpr 中の throw はすべてコンパイルエラーになるので、実行時に例外が投げられることはない。よって、これは明らかに誤検出。
しかし、NOLINT しようにも、(noexcept 中の) LOG_LP 等を使う行すべてを対象にしなければならず、負担が大きすぎる。

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

No branches or pull requests

2 participants