From commits-return-6794-archive-asf-public=cust-asf.ponee.io@zookeeper.apache.org Mon Aug 6 14:14:17 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 01F601807C5 for ; Mon, 6 Aug 2018 14:14:13 +0200 (CEST) Received: (qmail 55519 invoked by uid 500); 6 Aug 2018 12:14:12 -0000 Mailing-List: contact commits-help@zookeeper.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@zookeeper.apache.org Delivered-To: mailing list commits@zookeeper.apache.org Received: (qmail 52855 invoked by uid 99); 6 Aug 2018 12:14:11 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Aug 2018 12:14:11 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C86FDE0AC6; Mon, 6 Aug 2018 12:14:10 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: andor@apache.org To: commits@zookeeper.apache.org Date: Mon, 06 Aug 2018 12:14:30 -0000 Message-Id: In-Reply-To: <23d59816fc864cdcaa333309761a6f23@git.apache.org> References: <23d59816fc864cdcaa333309761a6f23@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [21/45] zookeeper git commit: ZOOKEEPER-3030: MAVEN MIGRATION - Step 1.3 - move contrib directories http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/AndOp.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/AndOp.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/AndOp.java new file mode 100644 index 0000000..581bdaa --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/AndOp.java @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.LogEntry; +import org.apache.zookeeper.graph.FilterOp; +import org.apache.zookeeper.graph.FilterException; + +public class AndOp extends FilterOp { + public boolean matches(LogEntry entry) throws FilterException { + for (FilterOp f : subOps) { + if (!f.matches(entry)) { + return false; + } + } + return true; + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/Arg.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/Arg.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/Arg.java new file mode 100644 index 0000000..4fda3cf --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/Arg.java @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.FilterOp.*; + +public class Arg { + private ArgType type; + protected T value; + + protected Arg(ArgType type) { + this.type = type; + } + + public ArgType getType() { return type; } + public T getValue() { return value; } + + public String toString() { + return "[" + type + ":" + value + "]"; + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/EqualsOp.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/EqualsOp.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/EqualsOp.java new file mode 100644 index 0000000..409815a --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/EqualsOp.java @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.LogEntry; +import org.apache.zookeeper.graph.FilterOp; +import org.apache.zookeeper.graph.FilterException; + +public class EqualsOp extends FilterOp { + public boolean matches(LogEntry entry) throws FilterException { + + Object last = null; + for (Arg a : args) { + Object v = a.getValue(); + if (a.getType() == FilterOp.ArgType.SYMBOL) { + String key = (String)a.getValue(); + v = entry.getAttribute(key); + } + + if (last != null + && !last.equals(v)) { + return false; + } + last = v; + } + + return true; + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/GreaterThanOp.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/GreaterThanOp.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/GreaterThanOp.java new file mode 100644 index 0000000..244dd3d --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/GreaterThanOp.java @@ -0,0 +1,70 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.LogEntry; +import org.apache.zookeeper.graph.FilterOp; +import org.apache.zookeeper.graph.FilterException; + +public class GreaterThanOp extends FilterOp { + public boolean matches(LogEntry entry) throws FilterException { + Arg first = args.get(0); + + if (first != null) { + FilterOp.ArgType type = first.getType(); + if (type == FilterOp.ArgType.SYMBOL) { + String key = (String)first.getValue(); + Object v = entry.getAttribute(key); + if (v instanceof String) { + type = FilterOp.ArgType.STRING; + } else if (v instanceof Double || v instanceof Long || v instanceof Integer || v instanceof Short) { + type = FilterOp.ArgType.NUMBER; + } else { + throw new FilterException("LessThanOp: Invalid argument, first argument resolves to neither a String nor a Number"); + } + } + + Object last = null; + for (Arg a : args) { + Object v = a.getValue(); + if (a.getType() == FilterOp.ArgType.SYMBOL) { + String key = (String)a.getValue(); + v = entry.getAttribute(key); + } + + if (last != null) { + if (type == FilterOp.ArgType.STRING) { + if (((String)last).compareTo((String)v) <= 0) { + return false; + } + } else if (type == FilterOp.ArgType.NUMBER) { + // System.out.println("last[" + ((Number)last).longValue() + "] v["+ ((Number)v).longValue() + "]"); + if (((Number)last).longValue() <= ((Number)v).longValue()) { + return false; + } + } + } + last = v; + } + return true; + } else { + return true; + } + } + +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/LessThanOp.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/LessThanOp.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/LessThanOp.java new file mode 100644 index 0000000..b7d9e09 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/LessThanOp.java @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.LogEntry; +import org.apache.zookeeper.graph.FilterOp; +import org.apache.zookeeper.graph.FilterException; + +public class LessThanOp extends FilterOp { + public boolean matches(LogEntry entry) throws FilterException { + Arg first = args.get(0); + + if (first != null) { + FilterOp.ArgType type = first.getType(); + if (type == FilterOp.ArgType.SYMBOL) { + String key = (String)first.getValue(); + Object v = entry.getAttribute(key); + if (v instanceof String) { + type = FilterOp.ArgType.STRING; + } else if (v instanceof Double || v instanceof Long || v instanceof Integer || v instanceof Short) { + type = FilterOp.ArgType.NUMBER; + } else { + throw new FilterException("LessThanOp: Invalid argument, first argument resolves to neither a String nor a Number"); + } + } + + Object last = null; + for (Arg a : args) { + Object v = a.getValue(); + if (a.getType() == FilterOp.ArgType.SYMBOL) { + String key = (String)a.getValue(); + v = entry.getAttribute(key); + } + + if (last != null) { + if (type == FilterOp.ArgType.STRING) { + if (((String)last).compareTo((String)v) >= 0) { + return false; + } + } else if (type == FilterOp.ArgType.NUMBER) { + if (((Number)last).doubleValue() >= ((Number)v).doubleValue()) { + return false; + } + } + } + last = v; + } + return true; + } else { + return true; + } + } + +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NotOp.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NotOp.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NotOp.java new file mode 100644 index 0000000..d8ed757 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NotOp.java @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.LogEntry; +import org.apache.zookeeper.graph.FilterOp; +import org.apache.zookeeper.graph.FilterException; + +public class NotOp extends FilterOp { + public boolean matches(LogEntry entry) throws FilterException { + if (subOps.size() != 1) { + throw new FilterException("Not operation can only take one argument"); + } + return !subOps.get(0).matches(entry); + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NumberArg.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NumberArg.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NumberArg.java new file mode 100644 index 0000000..d6b584d --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/NumberArg.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.FilterOp.*; + +public class NumberArg extends Arg { + public NumberArg(Long value) { + super(ArgType.NUMBER); + this.value = value; + } +}; + http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/OrOp.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/OrOp.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/OrOp.java new file mode 100644 index 0000000..d681589 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/OrOp.java @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.LogEntry; +import org.apache.zookeeper.graph.FilterOp; +import org.apache.zookeeper.graph.FilterException; + +public class OrOp extends FilterOp { + public boolean matches(LogEntry entry) throws FilterException { + for (FilterOp f : subOps) { + if (f.matches(entry)) { + return true; + } + } + return false; + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/StringArg.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/StringArg.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/StringArg.java new file mode 100644 index 0000000..7345d3c --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/StringArg.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.FilterOp.*; + +public class StringArg extends Arg { + public StringArg(String value) { + super(ArgType.STRING); + this.value = value; + } +}; + http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/SymbolArg.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/SymbolArg.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/SymbolArg.java new file mode 100644 index 0000000..077553b --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/SymbolArg.java @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.FilterOp.*; + +public class SymbolArg extends Arg { + public SymbolArg(String value) { + super(ArgType.SYMBOL); + this.value = value; + } +}; http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/XorOp.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/XorOp.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/XorOp.java new file mode 100644 index 0000000..9e778b1 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/filterops/XorOp.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.filterops; + +import org.apache.zookeeper.graph.LogEntry; +import org.apache.zookeeper.graph.FilterOp; +import org.apache.zookeeper.graph.FilterException; + +public class XorOp extends FilterOp { + public boolean matches(LogEntry entry) throws FilterException { + int count = 0; + for (FilterOp f : subOps) { + if (f.matches(entry)) { + count++; + if (count > 1) { + return false; + } + } + } + if (count == 1) { + return true; + } + return false; + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/FileLoader.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/FileLoader.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/FileLoader.java new file mode 100644 index 0000000..67e8945 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/FileLoader.java @@ -0,0 +1,60 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.servlets; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import org.apache.zookeeper.graph.*; + +public class FileLoader extends JsonServlet +{ + private MergedLogSource source = null; + + public FileLoader(MergedLogSource src) throws Exception { + source = src; + } + + String handleRequest(JsonRequest request) throws Exception + { + String output = ""; + + String file = request.getString("path", "/"); + JSONObject o = new JSONObject(); + try { + this.source.addSource(file); + o.put("status", "OK"); + + } catch (Exception e) { + o.put("status", "ERR"); + o.put("error", e.toString()); + } + + return JSONValue.toJSONString(o); + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Fs.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Fs.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Fs.java new file mode 100644 index 0000000..e5b1a01 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Fs.java @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.servlets; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import java.util.Arrays; +import java.util.Comparator; + +public class Fs extends JsonServlet +{ + String handleRequest(JsonRequest request) throws Exception + { + String output = ""; + JSONArray filelist = new JSONArray(); + + File base = new File(request.getString("path", "/")); + if (!base.exists() || !base.isDirectory()) { + throw new FileNotFoundException("Couldn't find [" + request + "]"); + } + File[] files = base.listFiles(); + Arrays.sort(files, new Comparator() { + public int compare(File o1, File o2) { + if (o1.isDirectory() != o2.isDirectory()) { + if (o1.isDirectory()) { + return -1; + } else { + return 1; + } + } + return o1.getName().compareToIgnoreCase(o2.getName()); + } + }); + + for (File f : files) { + JSONObject o = new JSONObject(); + o.put("file", f.getName()); + o.put("type", f.isDirectory() ? "D" : "F"); + o.put("path", f.getCanonicalPath()); + filelist.add(o); + } + return JSONValue.toJSONString(filelist); + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/GraphData.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/GraphData.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/GraphData.java new file mode 100644 index 0000000..fc10eb1 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/GraphData.java @@ -0,0 +1,85 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.servlets; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import org.apache.zookeeper.graph.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GraphData extends JsonServlet +{ + private static final Logger LOG = LoggerFactory.getLogger(GraphData.class); + private static final int DEFAULT_PERIOD = 1000; + + private LogSource source = null; + + public GraphData(LogSource src) throws Exception { + this.source = src; + } + + String handleRequest(JsonRequest request) throws Exception { + + + long starttime = 0; + long endtime = 0; + long period = 0; + FilterOp fo = null; + + starttime = request.getNumber("start", 0); + endtime = request.getNumber("end", 0); + period = request.getNumber("period", 0); + String filterstr = request.getString("filter", ""); + + if (filterstr.length() > 0) { + fo = new FilterParser(filterstr).parse(); + } + + if (starttime == 0) { starttime = source.getStartTime(); } + if (endtime == 0) { + if (period > 0) { + endtime = starttime + period; + } else { + endtime = starttime + DEFAULT_PERIOD; + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("handle(start= " + starttime + ", end=" + endtime + ", period=" + period + ")"); + } + + LogIterator iterator = (fo != null) ? + source.iterator(starttime, endtime, fo) : source.iterator(starttime, endtime); + return new JsonGenerator(iterator).toString(); + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/JsonServlet.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/JsonServlet.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/JsonServlet.java new file mode 100644 index 0000000..910d44f --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/JsonServlet.java @@ -0,0 +1,85 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.servlets; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.Map; + +abstract public class JsonServlet extends HttpServlet { + abstract String handleRequest(JsonRequest request) throws Exception; + + protected class JsonRequest { + private Map map; + + public JsonRequest(ServletRequest request) { + map = request.getParameterMap(); + } + + public long getNumber(String name, long defaultnum) { + String[] vals = (String[])map.get(name); + if (vals == null || vals.length == 0) { + return defaultnum; + } + + try { + return Long.valueOf(vals[0]); + } catch (NumberFormatException e) { + return defaultnum; + } + } + + public String getString(String name, String defaultstr) { + String[] vals = (String[])map.get(name); + if (vals == null || vals.length == 0) { + return defaultstr; + } else { + return vals[0]; + } + } + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + response.setContentType("text/plain;charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + + try { + String req = request.getRequestURI().substring(request.getServletPath().length()); + + response.getWriter().println(handleRequest(new JsonRequest(request))); + } catch (Exception e) { + JSONObject o = new JSONObject(); + o.put("error", e.toString()); + response.getWriter().println(JSONValue.toJSONString(o)); + } catch (java.lang.OutOfMemoryError oom) { + JSONObject o = new JSONObject(); + o.put("error", "Out of memory. Perhaps you've requested too many logs. Try narrowing you're filter criteria."); + response.getWriter().println(JSONValue.toJSONString(o)); + } + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/NumEvents.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/NumEvents.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/NumEvents.java new file mode 100644 index 0000000..5961a12 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/NumEvents.java @@ -0,0 +1,88 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.servlets; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import org.apache.zookeeper.graph.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class NumEvents extends JsonServlet +{ + private static final Logger LOG = LoggerFactory.getLogger(NumEvents.class); + private static final int DEFAULT_PERIOD = 1000; + + private LogSource source = null; + + public NumEvents(LogSource src) throws Exception { + this.source = src; + } + + String handleRequest(JsonRequest request) throws Exception { + String output = ""; + + long starttime = 0; + long endtime = 0; + long period = 0; + + starttime = request.getNumber("start", 0); + endtime = request.getNumber("end", 0); + period = request.getNumber("period", 0); + + if (starttime == 0) { starttime = source.getStartTime(); } + if (endtime == 0) { + if (period > 0) { + endtime = starttime + period; + } else { + endtime = source.getEndTime(); + } + } + + LogIterator iter = source.iterator(starttime, endtime); + JSONObject data = new JSONObject(); + data.put("startTime", starttime); + data.put("endTime", endtime); + long size = 0; + + size = iter.size(); + + data.put("numEntries", size); + if (LOG.isDebugEnabled()) { + LOG.debug("handle(start= " + starttime + ", end=" + endtime + ", numEntries=" + size +")"); + } + iter.close(); + return JSONValue.toJSONString(data); + } +} + http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/StaticContent.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/StaticContent.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/StaticContent.java new file mode 100644 index 0000000..d91acb6 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/StaticContent.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.servlets; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class StaticContent extends HttpServlet { + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + String path = request.getRequestURI().substring(request.getServletPath().length()); + + InputStream resource = ClassLoader.getSystemResourceAsStream("org/apache/zookeeper/graph/resources" + path); + if (resource == null) { + response.getWriter().println(path + " not found!"); + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + return; + } + try { + while (resource.available() > 0) { + response.getWriter().write(resource.read()); + } + } finally { + resource.close(); + } + // response.setContentType("text/plain;charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + } + +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Throughput.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Throughput.java b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Throughput.java new file mode 100644 index 0000000..341bf9e --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/java/org/apache/zookeeper/graph/servlets/Throughput.java @@ -0,0 +1,125 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zookeeper.graph.servlets; + +import java.io.IOException; +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.DataOutputStream; +import java.io.PrintStream; + +import java.util.HashSet; +import java.util.LinkedHashMap; + +import org.apache.zookeeper.graph.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + + +public class Throughput extends JsonServlet +{ + private static final int MS_PER_SEC = 1000; + private static final int MS_PER_MIN = MS_PER_SEC*60; + private static final int MS_PER_HOUR = MS_PER_MIN*60; + + private LogSource source = null; + + public Throughput(LogSource src) throws Exception { + this.source = src; + } + + public String handleRequest(JsonRequest request) throws Exception { + long starttime = 0; + long endtime = 0; + long period = 0; + long scale = 0; + + starttime = request.getNumber("start", 0); + endtime = request.getNumber("end", 0); + period = request.getNumber("period", 0); + + + if (starttime == 0) { starttime = source.getStartTime(); } + if (endtime == 0) { + if (period > 0) { + endtime = starttime + period; + } else { + endtime = source.getEndTime(); + } + } + + String scalestr = request.getString("scale", "minutes"); + if (scalestr.equals("seconds")) { + scale = MS_PER_SEC; + } else if (scalestr.equals("hours")) { + scale = MS_PER_HOUR; + } else { + scale = MS_PER_MIN; + } + + LogIterator iter = source.iterator(starttime, endtime); + + long current = 0; + long currentms = 0; + HashSet zxids_ms = new HashSet(); + long zxidcount = 0; + + JSONArray events = new JSONArray(); + while (iter.hasNext()) { + LogEntry e = iter.next(); + if (e.getType() != LogEntry.Type.TXN) { + continue; + } + + TransactionEntry cxn = (TransactionEntry)e; + + long ms = cxn.getTimestamp(); + long inscale = ms/scale; + + if (currentms != ms && currentms != 0) { + zxidcount += zxids_ms.size(); + zxids_ms.clear(); + } + + if (inscale != current && current != 0) { + JSONObject o = new JSONObject(); + o.put("time", current*scale); + o.put("count", zxidcount); + events.add(o); + zxidcount = 0; + } + current = inscale; + currentms = ms; + + zxids_ms.add(cxn.getZxid()); + } + JSONObject o = new JSONObject(); + o.put("time", current*scale); + o.put("count", zxidcount); + events.add(o); + + iter.close(); + + return JSONValue.toJSONString(events); + } + +}; http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph-dev.sh ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph-dev.sh b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph-dev.sh new file mode 100755 index 0000000..e04434e --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph-dev.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +make_canonical () { + cd $1; pwd; +} + +SCRIPTDIR=`dirname $0` +BUILDDIR=`make_canonical $SCRIPTDIR/../../../../../build/contrib/loggraph` +LIBDIR=`make_canonical $BUILDDIR/lib` +WEBDIR=`make_canonical $SCRIPTDIR/../web` +ZKDIR=`make_canonical $SCRIPTDIR/../../../../../build/` + +if [ ! -x $BUILDDIR ]; then + echo "\n\n*** You need to build loggraph before running it ***\n\n"; + exit; +fi + +for i in `ls $LIBDIR`; do + CLASSPATH=$LIBDIR/$i:$CLASSPATH +done + +for i in $ZKDIR/zookeeper-*.jar; do + CLASSPATH="$i:$CLASSPATH" +done + +CLASSPATH=$BUILDDIR/classes:$WEBDIR:$CLASSPATH +echo $CLASSPATH +java -Dlog4j.configuration=org/apache/zookeeper/graph/log4j.properties -Xdebug -Xrunjdwp:transport=dt_socket,address=4444,server=y,suspend=n -cp $CLASSPATH org.apache.zookeeper.graph.LogServer $* http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph.sh ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph.sh b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph.sh new file mode 100755 index 0000000..0259dc6 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/resources/loggraph.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +make_canonical () { + cd $1; pwd; +} + +SCRIPTDIR=`dirname $0` +BUILDDIR=`make_canonical $SCRIPTDIR/../../../../../build/contrib/loggraph` +LIBDIR=`make_canonical $BUILDDIR/lib` +ZKDIR=`make_canonical $SCRIPTDIR/../../../../../build/` + +if [ ! -x $BUILDDIR ]; then + echo "\n\n*** You need to build loggraph before running it ***\n\n"; + exit; +fi + +for i in `ls $LIBDIR`; do + CLASSPATH=$LIBDIR/$i:$CLASSPATH +done + +for i in `ls $BUILDDIR/*.jar`; do + CLASSPATH=$i:$CLASSPATH +done + +for i in $ZKDIR/zookeeper-*.jar; do + CLASSPATH="$i:$CLASSPATH" +done + +java -cp $CLASSPATH org.apache.zookeeper.graph.LogServer $* + + + + http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/log4j.properties ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/log4j.properties b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/log4j.properties new file mode 100644 index 0000000..ab8960b --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/log4j.properties @@ -0,0 +1,11 @@ +log4j.rootLogger=TRACE, CONSOLE + +# Print the date in ISO 8601 format +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.Threshold=TRACE +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n + +log4j.logger.org.apache.zookeeper.graph.LogSkipList=off +log4j.logger.org.apache.zookeeper.graph.RandomAccessFileReader=off +#log4j.logger.org.apache.zookeeper.graph.Log4JSource=off \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/date.format.js ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/date.format.js b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/date.format.js new file mode 100644 index 0000000..5515009 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/date.format.js @@ -0,0 +1,126 @@ +/* + * Date Format 1.2.3 + * (c) 2007-2009 Steven Levithan + * MIT license + * + * Includes enhancements by Scott Trenda + * and Kris Kowal + * + * Accepts a date, a mask, or a date and a mask. + * Returns a formatted version of the given date. + * The date defaults to the current date/time. + * The mask defaults to dateFormat.masks.default. + */ + +var dateFormat = function () { + var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, + timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, + timezoneClip = /[^-+\dA-Z]/g, + pad = function (val, len) { + val = String(val); + len = len || 2; + while (val.length < len) val = "0" + val; + return val; + }; + + // Regexes and supporting functions are cached through closure + return function (date, mask, utc) { + var dF = dateFormat; + + // You can't provide utc if you skip other args (use the "UTC:" mask prefix) + if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) { + mask = date; + date = undefined; + } + + // Passing date through Date applies Date.parse, if necessary + date = date ? new Date(date) : new Date; + if (isNaN(date)) throw SyntaxError("invalid date"); + + mask = String(dF.masks[mask] || mask || dF.masks["default"]); + + // Allow setting the utc argument via the mask + if (mask.slice(0, 4) == "UTC:") { + mask = mask.slice(4); + utc = true; + } + + var _ = utc ? "getUTC" : "get", + d = date[_ + "Date"](), + D = date[_ + "Day"](), + m = date[_ + "Month"](), + y = date[_ + "FullYear"](), + H = date[_ + "Hours"](), + M = date[_ + "Minutes"](), + s = date[_ + "Seconds"](), + L = date[_ + "Milliseconds"](), + o = utc ? 0 : date.getTimezoneOffset(), + flags = { + d: d, + dd: pad(d), + ddd: dF.i18n.dayNames[D], + dddd: dF.i18n.dayNames[D + 7], + m: m + 1, + mm: pad(m + 1), + mmm: dF.i18n.monthNames[m], + mmmm: dF.i18n.monthNames[m + 12], + yy: String(y).slice(2), + yyyy: y, + h: H % 12 || 12, + hh: pad(H % 12 || 12), + H: H, + HH: pad(H), + M: M, + MM: pad(M), + s: s, + ss: pad(s), + l: pad(L, 3), + L: pad(L > 99 ? Math.round(L / 10) : L), + t: H < 12 ? "a" : "p", + tt: H < 12 ? "am" : "pm", + T: H < 12 ? "A" : "P", + TT: H < 12 ? "AM" : "PM", + Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""), + o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), + S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10] + }; + + return mask.replace(token, function ($0) { + return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1); + }); + }; +}(); + +// Some common format strings +dateFormat.masks = { + "default": "ddd mmm dd yyyy HH:MM:ss", + shortDate: "m/d/yy", + mediumDate: "mmm d, yyyy", + longDate: "mmmm d, yyyy", + fullDate: "dddd, mmmm d, yyyy", + shortTime: "h:MM TT", + mediumTime: "h:MM:ss TT", + longTime: "h:MM:ss TT Z", + isoDate: "yyyy-mm-dd", + isoTime: "HH:MM:ss", + isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", + isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" +}; + +// Internationalization strings +dateFormat.i18n = { + dayNames: [ + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" + ], + monthNames: [ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" + ] +}; + +// For convenience... +Date.prototype.format = function (mask, utc) { + return dateFormat(this, mask, utc); +}; + http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.bar.js ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.bar.js b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.bar.js new file mode 100644 index 0000000..2f7212a --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.bar.js @@ -0,0 +1,385 @@ +/* + * g.Raphael 0.4 - Charting library, based on Raphaël + * + * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com) + * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. + */ +Raphael.fn.g.barchart = function (x, y, width, height, values, opts) { + opts = opts || {}; + var type = {round: "round", sharp: "sharp", soft: "soft"}[opts.type] || "square", + gutter = parseFloat(opts.gutter || "20%"), + chart = this.set(), + bars = this.set(), + covers = this.set(), + covers2 = this.set(), + total = Math.max.apply(Math, values), + stacktotal = [], + paper = this, + multi = 0, + colors = opts.colors || this.g.colors, + len = values.length; + if (this.raphael.is(values[0], "array")) { + total = []; + multi = len; + len = 0; + for (var i = values.length; i--;) { + bars.push(this.set()); + total.push(Math.max.apply(Math, values[i])); + len = Math.max(len, values[i].length); + } + if (opts.stacked) { + for (var i = len; i--;) { + var tot = 0; + for (var j = values.length; j--;) { + tot +=+ values[j][i] || 0; + } + stacktotal.push(tot); + } + } + for (var i = values.length; i--;) { + if (values[i].length < len) { + for (var j = len; j--;) { + values[i].push(0); + } + } + } + total = Math.max.apply(Math, opts.stacked ? stacktotal : total); + } + + total = (opts.to) || total; + var barwidth = width / (len * (100 + gutter) + gutter) * 100, + barhgutter = barwidth * gutter / 100, + barvgutter = opts.vgutter == null ? 20 : opts.vgutter, + stack = [], + X = x + barhgutter, + Y = (height - 2 * barvgutter) / total; + if (!opts.stretch) { + barhgutter = Math.round(barhgutter); + barwidth = Math.floor(barwidth); + } + !opts.stacked && (barwidth /= multi || 1); + for (var i = 0; i < len; i++) { + stack = []; + for (var j = 0; j < (multi || 1); j++) { + var h = Math.round((multi ? values[j][i] : values[i]) * Y), + top = y + height - barvgutter - h, + bar = this.g.finger(Math.round(X + barwidth / 2), top + h, barwidth, h, true, type).attr({stroke: colors[multi ? j : i], fill: colors[multi ? j : i]}); + if (multi) { + bars[j].push(bar); + } else { + bars.push(bar); + } + bar.y = top; + bar.x = Math.round(X + barwidth / 2); + bar.w = barwidth; + bar.h = h; + bar.value = multi ? values[j][i] : values[i]; + if (!opts.stacked) { + X += barwidth; + } else { + stack.push(bar); + } + } + if (opts.stacked) { + var cvr; + covers2.push(cvr = this.rect(stack[0].x - stack[0].w / 2, y, barwidth, height).attr(this.g.shim)); + cvr.bars = this.set(); + var size = 0; + for (var s = stack.length; s--;) { + stack[s].toFront(); + } + for (var s = 0, ss = stack.length; s < ss; s++) { + var bar = stack[s], + cover, + h = (size + bar.value) * Y, + path = this.g.finger(bar.x, y + height - barvgutter - !!size * .5, barwidth, h, true, type, 1); + cvr.bars.push(bar); + size && bar.attr({path: path}); + bar.h = h; + bar.y = y + height - barvgutter - !!size * .5 - h; + covers.push(cover = this.rect(bar.x - bar.w / 2, bar.y, barwidth, bar.value * Y).attr(this.g.shim)); + cover.bar = bar; + cover.value = bar.value; + size += bar.value; + } + X += barwidth; + } + X += barhgutter; + } + covers2.toFront(); + X = x + barhgutter; + if (!opts.stacked) { + for (var i = 0; i < len; i++) { + for (var j = 0; j < (multi || 1); j++) { + var cover; + covers.push(cover = this.rect(Math.round(X), y + barvgutter, barwidth, height - barvgutter).attr(this.g.shim)); + cover.bar = multi ? bars[j][i] : bars[i]; + cover.value = cover.bar.value; + X += barwidth; + } + X += barhgutter; + } + } + chart.label = function (labels, isBottom) { + labels = labels || []; + this.labels = paper.set(); + var L, l = -Infinity; + if (opts.stacked) { + for (var i = 0; i < len; i++) { + var tot = 0; + for (var j = 0; j < (multi || 1); j++) { + tot += multi ? values[j][i] : values[i]; + if (j == multi - 1) { + var label = paper.g.labelise(labels[i], tot, total); + L = paper.g.text(bars[i * (multi || 1) + j].x, y + height - barvgutter / 2, label).insertBefore(covers[i * (multi || 1) + j]); + var bb = L.getBBox(); + if (bb.x - 7 < l) { + L.remove(); + } else { + this.labels.push(L); + l = bb.x + bb.width; + } + } + } + } + } else { + for (var i = 0; i < len; i++) { + for (var j = 0; j < (multi || 1); j++) { + var label = paper.g.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total); + L = paper.g.text(bars[i * (multi || 1) + j].x, isBottom ? y + height - barvgutter / 2 : bars[i * (multi || 1) + j].y - 10, label).insertBefore(covers[i * (multi || 1) + j]); + var bb = L.getBBox(); + if (bb.x - 7 < l) { + L.remove(); + } else { + this.labels.push(L); + l = bb.x + bb.width; + } + } + } + } + return this; + }; + chart.hover = function (fin, fout) { + covers2.hide(); + covers.show(); + covers.mouseover(fin).mouseout(fout); + return this; + }; + chart.hoverColumn = function (fin, fout) { + covers.hide(); + covers2.show(); + fout = fout || function () {}; + covers2.mouseover(fin).mouseout(fout); + return this; + }; + chart.click = function (f) { + covers2.hide(); + covers.show(); + covers.click(f); + return this; + }; + chart.each = function (f) { + if (!Raphael.is(f, "function")) { + return this; + } + for (var i = covers.length; i--;) { + f.call(covers[i]); + } + return this; + }; + chart.eachColumn = function (f) { + if (!Raphael.is(f, "function")) { + return this; + } + for (var i = covers2.length; i--;) { + f.call(covers2[i]); + } + return this; + }; + chart.clickColumn = function (f) { + covers.hide(); + covers2.show(); + covers2.click(f); + return this; + }; + chart.push(bars, covers, covers2); + chart.bars = bars; + chart.covers = covers; + return chart; +}; +Raphael.fn.g.hbarchart = function (x, y, width, height, values, opts) { + opts = opts || {}; + var type = {round: "round", sharp: "sharp", soft: "soft"}[opts.type] || "square", + gutter = parseFloat(opts.gutter || "20%"), + chart = this.set(), + bars = this.set(), + covers = this.set(), + covers2 = this.set(), + total = Math.max.apply(Math, values), + stacktotal = [], + paper = this, + multi = 0, + colors = opts.colors || this.g.colors, + len = values.length; + if (this.raphael.is(values[0], "array")) { + total = []; + multi = len; + len = 0; + for (var i = values.length; i--;) { + bars.push(this.set()); + total.push(Math.max.apply(Math, values[i])); + len = Math.max(len, values[i].length); + } + if (opts.stacked) { + for (var i = len; i--;) { + var tot = 0; + for (var j = values.length; j--;) { + tot +=+ values[j][i] || 0; + } + stacktotal.push(tot); + } + } + for (var i = values.length; i--;) { + if (values[i].length < len) { + for (var j = len; j--;) { + values[i].push(0); + } + } + } + total = Math.max.apply(Math, opts.stacked ? stacktotal : total); + } + + total = (opts.to) || total; + var barheight = Math.floor(height / (len * (100 + gutter) + gutter) * 100), + bargutter = Math.floor(barheight * gutter / 100), + stack = [], + Y = y + bargutter, + X = (width - 1) / total; + !opts.stacked && (barheight /= multi || 1); + for (var i = 0; i < len; i++) { + stack = []; + for (var j = 0; j < (multi || 1); j++) { + var val = multi ? values[j][i] : values[i], + bar = this.g.finger(x, Y + barheight / 2, Math.round(val * X), barheight - 1, false, type).attr({stroke: colors[multi ? j : i], fill: colors[multi ? j : i]}); + if (multi) { + bars[j].push(bar); + } else { + bars.push(bar); + } + bar.x = x + Math.round(val * X); + bar.y = Y + barheight / 2; + bar.w = Math.round(val * X); + bar.h = barheight; + bar.value = +val; + if (!opts.stacked) { + Y += barheight; + } else { + stack.push(bar); + } + } + if (opts.stacked) { + var cvr = this.rect(x, stack[0].y - stack[0].h / 2, width, barheight).attr(this.g.shim); + covers2.push(cvr); + cvr.bars = this.set(); + var size = 0; + for (var s = stack.length; s--;) { + stack[s].toFront(); + } + for (var s = 0, ss = stack.length; s < ss; s++) { + var bar = stack[s], + cover, + val = Math.round((size + bar.value) * X), + path = this.g.finger(x, bar.y, val, barheight - 1, false, type, 1); + cvr.bars.push(bar); + size && bar.attr({path: path}); + bar.w = val; + bar.x = x + val; + covers.push(cover = this.rect(x + size * X, bar.y - bar.h / 2, bar.value * X, barheight).attr(this.g.shim)); + cover.bar = bar; + size += bar.value; + } + Y += barheight; + } + Y += bargutter; + } + covers2.toFront(); + Y = y + bargutter; + if (!opts.stacked) { + for (var i = 0; i < len; i++) { + for (var j = 0; j < multi; j++) { + var cover = this.rect(x, Y, width, barheight).attr(this.g.shim); + covers.push(cover); + cover.bar = bars[j][i]; + Y += barheight; + } + Y += bargutter; + } + } + chart.label = function (labels, isRight) { + labels = labels || []; + this.labels = paper.set(); + for (var i = 0; i < len; i++) { + for (var j = 0; j < multi; j++) { + var label = paper.g.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total); + var X = isRight ? bars[i * (multi || 1) + j].x - barheight / 2 + 3 : x + 5, + A = isRight ? "end" : "start", + L; + this.labels.push(L = paper.g.text(X, bars[i * (multi || 1) + j].y, label).attr({"text-anchor": A}).insertBefore(covers[0])); + if (L.getBBox().x < x + 5) { + L.attr({x: x + 5, "text-anchor": "start"}); + } else { + bars[i * (multi || 1) + j].label = L; + } + } + } + return this; + }; + chart.hover = function (fin, fout) { + covers2.hide(); + covers.show(); + fout = fout || function () {}; + covers.mouseover(fin).mouseout(fout); + return this; + }; + chart.hoverColumn = function (fin, fout) { + covers.hide(); + covers2.show(); + fout = fout || function () {}; + covers2.mouseover(fin).mouseout(fout); + return this; + }; + chart.each = function (f) { + if (!Raphael.is(f, "function")) { + return this; + } + for (var i = covers.length; i--;) { + f.call(covers[i]); + } + return this; + }; + chart.eachColumn = function (f) { + if (!Raphael.is(f, "function")) { + return this; + } + for (var i = covers2.length; i--;) { + f.call(covers2[i]); + } + return this; + }; + chart.click = function (f) { + covers2.hide(); + covers.show(); + covers.click(f); + return this; + }; + chart.clickColumn = function (f) { + covers.hide(); + covers2.show(); + covers2.click(f); + return this; + }; + chart.push(bars, covers, covers2); + chart.bars = bars; + chart.covers = covers; + return chart; +}; http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.dot.js ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.dot.js b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.dot.js new file mode 100644 index 0000000..2821e62 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.dot.js @@ -0,0 +1,110 @@ +/* + * g.Raphael 0.4 - Charting library, based on Raphaël + * + * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com) + * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. + */ +Raphael.fn.g.dotchart = function (x, y, width, height, valuesx, valuesy, size, opts) { + function drawAxis(ax) { + +ax[0] && (ax[0] = paper.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.axisxlabels || null, opts.axisxtype || "t")); + +ax[1] && (ax[1] = paper.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.axisylabels || null, opts.axisytype || "t")); + +ax[2] && (ax[2] = paper.g.axis(x + gutter, y + height - gutter + maxR, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.axisxlabels || null, opts.axisxtype || "t")); + +ax[3] && (ax[3] = paper.g.axis(x + gutter - maxR, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.axisylabels || null, opts.axisytype || "t")); + } + opts = opts || {}; + var xdim = this.g.snapEnds(Math.min.apply(Math, valuesx), Math.max.apply(Math, valuesx), valuesx.length - 1), + minx = xdim.from, + maxx = xdim.to, + gutter = opts.gutter || 10, + ydim = this.g.snapEnds(Math.min.apply(Math, valuesy), Math.max.apply(Math, valuesy), valuesy.length - 1), + miny = ydim.from, + maxy = ydim.to, + len = Math.max(valuesx.length, valuesy.length, size.length), + symbol = this.g.markers[opts.symbol] || "disc", + res = this.set(), + series = this.set(), + max = opts.max || 100, + top = Math.max.apply(Math, size), + R = [], + paper = this, + k = Math.sqrt(top / Math.PI) * 2 / max; + + for (var i = 0; i < len; i++) { + R[i] = Math.min(Math.sqrt(size[i] / Math.PI) * 2 / k, max); + } + gutter = Math.max.apply(Math, R.concat(gutter)); + var axis = this.set(), + maxR = Math.max.apply(Math, R); + if (opts.axis) { + var ax = (opts.axis + "").split(/[,\s]+/); + drawAxis(ax); + var g = [], b = []; + for (var i = 0, ii = ax.length; i < ii; i++) { + var bb = ax[i].all ? ax[i].all.getBBox()[["height", "width"][i % 2]] : 0; + g[i] = bb + gutter; + b[i] = bb; + } + gutter = Math.max.apply(Math, g.concat(gutter)); + for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) { + ax[i].remove(); + ax[i] = 1; + } + drawAxis(ax); + for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) { + axis.push(ax[i].all); + } + res.axis = axis; + } + var kx = (width - gutter * 2) / ((maxx - minx) || 1), + ky = (height - gutter * 2) / ((maxy - miny) || 1); + for (var i = 0, ii = valuesy.length; i < ii; i++) { + var sym = this.raphael.is(symbol, "array") ? symbol[i] : symbol, + X = x + gutter + (valuesx[i] - minx) * kx, + Y = y + height - gutter - (valuesy[i] - miny) * ky; + sym && R[i] && series.push(this.g[sym](X, Y, R[i]).attr({fill: opts.heat ? this.g.colorValue(R[i], maxR) : Raphael.fn.g.colors[0], "fill-opacity": opts.opacity ? R[i] / max : 1, stroke: "none"})); + } + var covers = this.set(); + for (var i = 0, ii = valuesy.length; i < ii; i++) { + var X = x + gutter + (valuesx[i] - minx) * kx, + Y = y + height - gutter - (valuesy[i] - miny) * ky; + covers.push(this.circle(X, Y, maxR).attr(this.g.shim)); + opts.href && opts.href[i] && covers[i].attr({href: opts.href[i]}); + covers[i].r = +R[i].toFixed(3); + covers[i].x = +X.toFixed(3); + covers[i].y = +Y.toFixed(3); + covers[i].X = valuesx[i]; + covers[i].Y = valuesy[i]; + covers[i].value = size[i] || 0; + covers[i].dot = series[i]; + } + res.covers = covers; + res.series = series; + res.push(series, axis, covers); + res.hover = function (fin, fout) { + covers.mouseover(fin).mouseout(fout); + return this; + }; + res.click = function (f) { + covers.click(f); + return this; + }; + res.each = function (f) { + if (!Raphael.is(f, "function")) { + return this; + } + for (var i = covers.length; i--;) { + f.call(covers[i]); + } + return this; + }; + res.href = function (map) { + var cover; + for (var i = covers.length; i--;) { + cover = covers[i]; + if (cover.X == map.x && cover.Y == map.y && cover.value == map.value) { + cover.attr({href: map.href}); + } + } + }; + return res; +}; http://git-wip-us.apache.org/repos/asf/zookeeper/blob/eab8c1eb/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.line.js ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.line.js b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.line.js new file mode 100644 index 0000000..eb56e59 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-loggraph/src/main/webapp/org/apache/zookeeper/graph/resources/g.line.js @@ -0,0 +1,230 @@ +/* + * g.Raphael 0.4 - Charting library, based on Raphaël + * + * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com) + * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. + */ +Raphael.fn.g.linechart = function (x, y, width, height, valuesx, valuesy, opts) { + function shrink(values, dim) { + var k = values.length / dim, + j = 0, + l = k, + sum = 0, + res = []; + while (j < values.length) { + l--; + if (l < 0) { + sum += values[j] * (1 + l); + res.push(sum / k); + sum = values[j++] * -l; + l += k; + } else { + sum += values[j++]; + } + } + return res; + } + opts = opts || {}; + if (!this.raphael.is(valuesx[0], "array")) { + valuesx = [valuesx]; + } + if (!this.raphael.is(valuesy[0], "array")) { + valuesy = [valuesy]; + } + var allx = Array.prototype.concat.apply([], valuesx), + ally = Array.prototype.concat.apply([], valuesy), + xdim = this.g.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1), + minx = xdim.from, + maxx = xdim.to, + gutter = opts.gutter || 10, + kx = (width - gutter * 2) / (maxx - minx), + ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1), + miny = ydim.from, + maxy = ydim.to, + ky = (height - gutter * 2) / (maxy - miny), + len = Math.max(valuesx[0].length, valuesy[0].length), + symbol = opts.symbol || "", + colors = opts.colors || Raphael.fn.g.colors, + that = this, + columns = null, + dots = null, + chart = this.set(), + path = []; + + for (var i = 0, ii = valuesy.length; i < ii; i++) { + len = Math.max(len, valuesy[i].length); + } + var shades = this.set(); + for (var i = 0, ii = valuesy.length; i < ii; i++) { + if (opts.shade) { + shades.push(this.path().attr({stroke: "none", fill: colors[i], opacity: opts.nostroke ? 1 : .3})); + } + if (valuesy[i].length > width - 2 * gutter) { + valuesy[i] = shrink(valuesy[i], width - 2 * gutter); + len = width - 2 * gutter; + } + if (valuesx[i] && valuesx[i].length > width - 2 * gutter) { + valuesx[i] = shrink(valuesx[i], width - 2 * gutter); + } + } + var axis = this.set(); + if (opts.axis) { + var ax = (opts.axis + "").split(/[,\s]+/); + +ax[0] && axis.push(this.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.northlabels)); + +ax[1] && axis.push(this.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.eastlabels)); + +ax[2] && axis.push(this.g.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.southlabels)); + +ax[3] && axis.push(this.g.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.westlabels)); + } + if (opts.northAxisLabel) { + this.g.text(x + gutter + width/2, gutter, opts.northAxisLabel); + } + if (opts.southAxisLabel) { + this.g.text(x + gutter + width/2, y + height + 20, opts.southAxisLabel); + } + if (opts.westAxisLabel) { + this.g.text(gutter, y + gutter + height/2, opts.westAxisLabel).attr({rotation: -90}); + } + if (opts.eastAxisLabel) { + this.g.text(x + gutter + width + 20, y + gutter + height/2, opts.eastAxisLabel).attr({rotation: 90}); + } + + var lines = this.set(), + symbols = this.set(), + line; + for (var i = 0, ii = valuesy.length; i < ii; i++) { + if (!opts.nostroke) { + lines.push(line = this.path().attr({ + stroke: colors[i], + "stroke-width": opts.width || 2, + "stroke-linejoin": "round", + "stroke-linecap": "round", + "stroke-dasharray": opts.dash || "" + })); + } + var sym = this.raphael.is(symbol, "array") ? symbol[i] : symbol, + symset = this.set(); + path = []; + for (var j = 0, jj = valuesy[i].length; j < jj; j++) { + var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx; + var Y = y + height - gutter - (valuesy[i][j] - miny) * ky; + (Raphael.is(sym, "array") ? sym[j] : sym) && symset.push(this.g[Raphael.fn.g.markers[this.raphael.is(sym, "array") ? sym[j] : sym]](X, Y, (opts.width || 2) * 3).attr({fill: colors[i], stroke: "none"})); + path = path.concat([j ? "L" : "M", X, Y]); + } + symbols.push(symset); + if (opts.shade) { + shades[i].attr({path: path.concat(["L", X, y + height - gutter, "L", x + gutter + ((valuesx[i] || valuesx[0])[0] - minx) * kx, y + height - gutter, "z"]).join(",")}); + } + !opts.nostroke && line.attr({path: path.join(",")}); + } + function createColumns(f) { + // unite Xs together + var Xs = []; + for (var i = 0, ii = valuesx.length; i < ii; i++) { + Xs = Xs.concat(valuesx[i]); + } + Xs.sort(); + // remove duplicates + var Xs2 = [], + xs = []; + for (var i = 0, ii = Xs.length; i < ii; i++) { + Xs[i] != Xs[i - 1] && Xs2.push(Xs[i]) && xs.push(x + gutter + (Xs[i] - minx) * kx); + } + Xs = Xs2; + ii = Xs.length; + var cvrs = f || that.set(); + for (var i = 0; i < ii; i++) { + var X = xs[i] - (xs[i] - (xs[i - 1] || x)) / 2, + w = ((xs[i + 1] || x + width) - xs[i]) / 2 + (xs[i] - (xs[i - 1] || x)) / 2, + C; + f ? (C = {}) : cvrs.push(C = that.rect(X - 1, y, Math.max(w + 1, 1), height).attr({stroke: "none", fill: "#000", opacity: 0})); + C.values = []; + C.symbols = that.set(); + C.y = []; + C.x = xs[i]; + C.axis = Xs[i]; + for (var j = 0, jj = valuesy.length; j < jj; j++) { + Xs2 = valuesx[j] || valuesx[0]; + for (var k = 0, kk = Xs2.length; k < kk; k++) { + if (Xs2[k] == Xs[i]) { + C.values.push(valuesy[j][k]); + C.y.push(y + height - gutter - (valuesy[j][k] - miny) * ky); + C.symbols.push(chart.symbols[j][k]); + } + } + } + f && f.call(C); + } + !f && (columns = cvrs); + } + function createDots(f) { + var cvrs = f || that.set(), + C; + for (var i = 0, ii = valuesy.length; i < ii; i++) { + for (var j = 0, jj = valuesy[i].length; j < jj; j++) { + var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx, + nearX = x + gutter + ((valuesx[i] || valuesx[0])[j ? j - 1 : 1] - minx) * kx, + Y = y + height - gutter - (valuesy[i][j] - miny) * ky; + f ? (C = {}) : cvrs.push(C = that.circle(X, Y, Math.abs(nearX - X) / 2).attr({stroke: "none", fill: "#000", opacity: 0})); + C.x = X; + C.y = Y; + C.value = valuesy[i][j]; + C.line = chart.lines[i]; + C.shade = chart.shades[i]; + C.symbol = chart.symbols[i][j]; + C.symbols = chart.symbols[i]; + C.axis = (valuesx[i] || valuesx[0])[j]; + f && f.call(C); + } + } + !f && (dots = cvrs); + } + chart.push(lines, shades, symbols, axis, columns, dots); + chart.lines = lines; + chart.shades = shades; + chart.symbols = symbols; + chart.axis = axis; + chart.hoverColumn = function (fin, fout) { + !columns && createColumns(); + columns.mouseover(fin).mouseout(fout); + return this; + }; + chart.clickColumn = function (f) { + !columns && createColumns(); + columns.click(f); + return this; + }; + chart.hrefColumn = function (cols) { + var hrefs = that.raphael.is(arguments[0], "array") ? arguments[0] : arguments; + if (!(arguments.length - 1) && typeof cols == "object") { + for (var x in cols) { + for (var i = 0, ii = columns.length; i < ii; i++) if (columns[i].axis == x) { + columns[i].attr("href", cols[x]); + } + } + } + !columns && createColumns(); + for (var i = 0, ii = hrefs.length; i < ii; i++) { + columns[i] && columns[i].attr("href", hrefs[i]); + } + return this; + }; + chart.hover = function (fin, fout) { + !dots && createDots(); + dots.mouseover(fin).mouseout(fout); + return this; + }; + chart.click = function (f) { + !dots && createDots(); + dots.click(f); + return this; + }; + chart.each = function (f) { + createDots(f); + return this; + }; + chart.eachColumn = function (f) { + createColumns(f); + return this; + }; + return chart; +};