/** * Licensed to Cloudera, Inc. under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. Cloudera, Inc. 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 com.cloudera.flume.handlers.rolling; import java.nio.ByteBuffer; import java.text.DateFormat; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.cloudera.flume.core.Event; import com.cloudera.util.Clock; /** * This tagger uses process name and pid as its prefix to manage log write-ahead * files. It uses a file name convention and to tag on batches of events. */ public class ProcessTagger implements Tagger { private final static Pattern p = Pattern .compile(".*\\.(\\d+)\\.(\\d+-\\d+-\\d+)\\.seq"); private final static String DATE_FORMAT = "yyyyMMdd-HHmmssSSSZ"; /** * These event attributes names are used to keep some group information on * events. */ public final static String A_TID = "tid"; public final static String A_EXE = "exe"; String lastTag; Date last; String exe; long pid; public ProcessTagger() { } public String createTag(String name, int pid) { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); String f; f = dateFormat.format(new Date(Clock.unixTime())); if (name.length() > 200) { name = name.substring(0, 200); // concatenate long prefixes } String fname = String.format("%s.%08d.%s.seq", name, pid, f); return fname; } public static Date extractDate(String s) { DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); if (s == null) return null; Matcher m = p.matcher(s); if (!m.find()) { return null; } String date = m.group(2); Date d = dateFormat.parse(date, new ParsePosition(0)); return d; } @Override public String getTag() { return lastTag; } @Override public String newTag() { DateFormat dateFormat2 = new SimpleDateFormat(DATE_FORMAT); long pid = Thread.currentThread().getId(); String prefix = "log"; Date now = new Date(Clock.unixTime()); long nanos = Clock.nanos(); String f; // see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6231579 synchronized (dateFormat2) { f = dateFormat2.format(now); } if (prefix.length() > 200) { prefix = prefix.substring(0, 200); // concatenate long prefixes } lastTag = String.format("%s.%08d.%s.%012d.seq", prefix, pid, f, nanos); this.pid = pid; this.exe = prefix; this.last = now; return lastTag; } @Override public Date getDate() { if (last == null) { return new Date(0); } return new Date(last.getTime()); // Defensive copy } @Override public void annotate(Event e) { // ByteBuffer one liners are to convert longs to byte[8]s. e.set(A_TID, ByteBuffer.allocate(8).putLong(pid).array()); e.set(A_EXE, exe.getBytes()); e.set(A_TXID, ByteBuffer.allocate(8).putLong(last.getTime()).array()); } }