in common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/impl/VertxRestAccessLogPatternParser.java [169:216]
private List<AccessLogItemLocation> matchAccessLogItem(String rawPattern) {
List<AccessLogItemLocation> locationList = new ArrayList<>();
int cursor = 0;
while (cursor < rawPattern.length()) {
AccessLogItemLocation candidate = null;
for (VertxRestAccessLogItemMeta meta : metaList) {
if (null != candidate && null == meta.getSuffix()) {
// TODO:
// if user define item("%{","}ab") and item("%{_","}abc") and the pattern is "%{_var}ab}abc"
// currently the result is item("%{","_var","}ab"), plaintext("}abc")
// is this acceptable?
// We've gotten an AccessLogItem with suffix, so there is no need to match those without suffix,
// just break this match loop
cursor = candidate.tail;
break;
}
if (rawPattern.startsWith(meta.getPrefix(), cursor)) {
if (null == meta.getSuffix()) {
// for simple type AccessLogItem, there is no need to try to match the next item.
candidate = new AccessLogItemLocation(cursor, meta);
cursor = candidate.tail;
break;
}
// for configurable type, like %{...}i, more check is needed
// e.g. "%{varName1}o ${varName2}i" should be divided into
// ResponseHeaderItem with varName="varName1" and RequestHeaderItem with varName="varName2"
// INSTEAD OF RequestHeaderItem with varName="varName1}o ${varName2"
int rear = rawPattern.indexOf(meta.getSuffix(), cursor);
if (rear < 0) {
continue;
}
if (null == candidate || rear < candidate.suffixIndex) {
candidate = new AccessLogItemLocation(cursor, rear, meta);
}
// There is a matched item which is in front of this item, so this item is ignored.
}
}
if (candidate == null) {
++cursor;
continue;
}
locationList.add(candidate);
}
return locationList;
}