-
Notifications
You must be signed in to change notification settings - Fork 26.5k
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
Acesslog dateformat enhancemnet #3090
Acesslog dateformat enhancemnet #3090
Conversation
Update from upstream
master synch
Sync of master
Master sync
Master sync
Master sync
Master sync
Codecov Report
@@ Coverage Diff @@
## master #3090 +/- ##
============================================
+ Coverage 63.5% 63.72% +0.21%
Complexity 75 75
============================================
Files 653 654 +1
Lines 28251 28256 +5
Branches 4816 4781 -35
============================================
+ Hits 17942 18005 +63
+ Misses 8040 7997 -43
+ Partials 2269 2254 -15
Continue to review full report at Codecov.
|
@carryxyh could you please review this. |
I didn't look into the change closely, but it looks like we are now moving the date formatter into one single thread to avoid contention completely, which I believe it is the right direction as I pointed out in the old pull request :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not thread safe
@zonghaishang |
@zonghaishang could you please provide the details about the thread safety so that I can work on this? @beiwei30 Is there something to incorporate which you feel here? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can make the log queue static.
What do u think?
} | ||
if (logSet.size() < LOG_MAX_BUFFER) { | ||
logSet.add(logmessage); | ||
private static final InternalThreadLocal<SimpleDateFormat> INLINE_MESSAGE_DATE_FORMATTER = new InternalThreadLocal<SimpleDateFormat>() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this filed is never used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. I will remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
private volatile ScheduledFuture<?> logFuture = null; | ||
private final ConcurrentMap<String, Set<AccessLogData>> logQueue = new ConcurrentHashMap<String, Set<AccessLogData>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this field be static?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it make sense now to make it static as it is now bound to single thread.
In addition to this, I was thinking (correct me If I am wrong), instead of defining the logQueue as a member of this class, we can it get through a factory (although factory will supply single queue only), so that in future even if we have change it based on our defined we don't have to touch this class. May be we can do this as part of separate PR. What do you say?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emmm...
What is this factory produce? Maybe I haven't get your point~ Can u give more details?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it provide the storage object which its consumer object,
e.g.
Store store= InMemoryQueueStorageFactory.getInstance().getStore();
store.add(accessLog);
something like above. The above example what I hvae given may not be very intuitive itself for explaination, but for high level understanding it might help. If you want I might create a sample branch to demonestrate in more detail way by having some implementation. What do you say?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally think that it is not necessary, because it will make the code more complicated. I think that the current structure is relatively simple, haha.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😄
dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java
Outdated
Show resolved
Hide resolved
} catch (Exception e) { | ||
logger.error(e.getMessage(), e); | ||
private void log(String accessLog, AccessLogData accessLogData) { | ||
Set<AccessLogData> logSet = logQueue.get(accessLog); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use computeIfAbsent to optimize this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java
Outdated
Show resolved
Hide resolved
@carryxyh I have made the changes, would you plz review it. |
@khanimteyaz |
@zonghaishang would you care to provide some detail on the thread safety, so that I can incorporate them? FYI I have provided the comment in previous section about the implementation. |
I have updated with comment, would you review my pr? |
@zonghaishang @khanimteyaz |
Why not introducing I think it's more simple and make sense. |
@jasonjoo2010 |
Yes, it's thread-safe by implemented no sharing data and also including instances cache. Generally we can just call |
@khanimteyaz Thx for your suggestion. @jasonjoo2010 |
But it's in |
SimpleDateFormat is not thread-safe, which is why we have to create new objects every time before. I did some research. Java8 currently has a thread-safe date tool called LocalDateTime. After reviewing @jasonjoo2010 's recommendation, I did some testing and found that FastDateFormat performs much better than the other two. Therefore, I also recommend FastDateFormat, but I prefer to bring it into the dubbo-commom package as a common date tool for other modules to reuse.You can refer to the data in the table below. The first column is the number of samples, and the following data is the average time corresponding to each sample in ms.
Note : For environmental reasons, the above data are for reference only |
Do we copy code into dubbo? |
Release resource after use in ConfigParserTest
add javadoc for registry and optimize code
* code optimization * useless import * optimization
code optimization
Add javadoc for dubbo-serialization module(apache#3002).
* optimize log output * Separate logs for reconnect and close * remove reconnect exception log
* modify some log describe * use java8 lambda expression
* fix telnet trace times is always 1 * use StringUtils determine if the string is empty * Fix 3105 , make invoke command with Json string parameter without "class" key * Fix 3105 ,Keep the class key to support overloaded methods * optimize InvokerTelnetHandlerTest
* upgrade junit to junit5 * modify test * 批量修改upgrade_junt_to_junit5 * 删除多余的文件 * fi test case * Disabled soem test case temporarily * upgrade junit to junit5 and batch modify test case * copy some code from jupiter5.4.0.M1 for some issues * 修改rat福泽 * update rat path * revert case * add junit-platform-surefire-provider to maven-surefire-plugin * update dependency * fix coverage issue (#1) * use jupiter 5.4.0-M1 and remove junit5 source code
…backService method issue. (apache#3199) * Optimize the code: fix url to null, NullPointerException, change private variable to camel mode. * Optimize the code: exportOrUnexportCallbackService method camel mode. * Optimize the code: fix method:encodeInvocationArgument private callbackStatus is camel writing. * Optimize the code: fix name issue * Exporter is a noun, we should use a verb here, like Export. * The generics that can be inferred automatically are also deleted.
* refactor telnet invoke command * add select command for telnet * fix test case
* wrong event setting * modify event seeting * modify
* Code optimization, call the util method * mofidy * modify * * import package
* qos heart question fix apache#3165 * modify * judge if it's a IdleStateEvent * add UT * modify
* modify some typos * fix some other addionalParameterKeys and paramter typos
* must shutdown thread pool when no in use
What is the purpose of the change
AcceLogFilter message creation and last and current check was performing by each time simple date formate object creation. In this version of code I have use the ThreadLocal for each thread wise to create simple date format object instead of each call
#3026
In this PR
- Method naming
- Reducing big methods to small.
This PR is a resurrection of old PR
Sorry for the inconvenience
Brief changelog
XXXXX
Verifying this change
Runnig UT and verifying generated access log.
Follow this checklist to help us incorporate your contribution quickly and easily:
[Dubbo-XXX] Fix UnknownException when host config not exist #XXX
. Each commit in the pull request should have a meaningful subject line and body.mvn clean install -DskipTests=false
&mvn clean test-compile failsafe:integration-test
to make sure unit-test and integration-test pass.