この例では、参照用のユーザーログインとアップロードサーバーを読み取るための特定の実装コードを共有しています。特定のコンテンツは次のとおりです
クライアントは、ユーザーにUNIXサービスを提供するサーバーで実行します。サーバー上のユーザーの上流および下流の情報を読み取り、収集するために使用され、ペアリングして整理してから、サマリーのためにサーバーに送信します。
特定の実装コード:
1。DMSSERVER.JAVA
パッケージcom.dms; java.io.bufferedreader; Import java.io.file; Import java.io.fileoutputStream; Import java.io.ioexception; Import java.io.inputStreamReader; Import Java.io.OutputStreamWriter; Import Java.io.io.Printwriter; Import Import.Net.Net.Serversocket; java.util.hashmap; Import java.util.list; import java.util.map; import java.util.concurrent.blockingqueue; Import java.util.concurrent.executorservice; Import java.util.util.concurrent.executors; import.util.util.util.current.linkblockyuu; Import org.dom4j.document; Import org.dom4j.element; Import org.dom4j.io.saxreader; /** * DMSサーバーは、各クライアントから送信されたペアリングログを受信し、ローカルファイルに保存 * @Author Administrator * */Public Class DMSServer {// Property Definition // Serversocket Private Serversocket Serverをクライアントに接続したサーバーを受信するために使用されます。 //クライアントを処理するスレッドを管理するために使用されるスレッドプールプライベートエグゼクティブサービススレッドプール。 //クライアントから送信されたすべてのファイルをログにペアリングするために保存しますプライベートファイルserverlogfile; //メッセージキュープライベートブロッキングキュー<文字列> messagequeue = new linkedblockingqueue <string>(); public dmsserver()スロー例外{try {system.out.println( "サーバーが初期化..."); // 1コンフィギュレーションファイルserver-config.xmlマップ<string、string> config = loadconfig(); // 2属性init(config)を初期化します。 System.out.println( "サーバー初期化が完了..."); } catch(Exception E){System.out.println( "初期化に失敗!"); eを投げる; }} / ***コンストラクターメソッドを初期化する最初のステップは、構成ファイルを解析することです。* @return構成ファイルの各アイテムに返されたマップが保存されます。キー:タグの名前* @throws例外* / privateマップ<文字列> loadconfig()throws {try {try {saxreader reader = saxreader reader(); document doc = reader.read(new file( "server-config.xml"));要素root = doc.getRootelement(); map <string、string> config = new hashmap <string、string>(); /**すべてのサブタグを<config>タグ*に取得し、各サブタグの名前をキーとして保存し、中央の*テキストはマップコレクションの値です*/ list <要素> list = root.elements(); for(要素e:list){string key = e.getname();文字列値= e.getTextTrim(); config.put(key、value); } config; } catch(Exception e){System.out.println( "Configurationファイルの例外を解決!"); e.printstacktrace(); eを投げる; }} /** *コンストラクターメソッドの初期化の2番目のステップは、構成項目に従って属性を初期化することです。作成されました。この値は、スレッドプールスレッドの数として使用されます*構成ファイル:サーバーの<serverport>でプロパティを初期化します。ここでは、この値はサーバーポートのServersocket*/ this.server = new Serversocket(integer.parseint(config.get( "serverport")))); this.serverlogfile = new file(config.get( "logrecfile")); this.threadpool = executors.newfixedthreadpool(integer.parseint(config.get( "threadsum"))); } /** *サーバーで作業を開始する方法 * @Throws例外 * /public void start()スロー例外{ / * *実装要件: *最初にスレッドを個別に起動してSaveloghandlerを実行します *このタスクはすべてのペアリングログ *を保存し、サーバーポートループを聴き始めることです。クライアントが接続されたら、 *クライアントハンダーをインスタンス化し、タスクをスレッドプール *に引き渡して、クライアントとの対話を処理するスレッドを割り当てます。 * */ try {system.out.println( "サーバーが動作を開始..."); saveloghandler slh = new Saveloghandler();新しいスレッド(slh).start(); while(true){socket socket = server.accept(); threadpool.execute(new ClientHandler(socket)); }} catch(例外e){e.printstacktrace(); eを投げる; }} public static void main(string [] args){try {dmsserver server = new dmsserver(); server.start(); } catch(Exception E){System.out.println( "ステーションはサーバーの起動に失敗しました!"); }}} / ** *このスレッドは、メッセージキューから各ペアログを取得し、serverlogfileファイル * @author Administrator * * / private class saveloghandlerを実装してrunnable {public void run(){printwriter pw = null; try {pw = new PrintWriter(new fileoutputStream(serverLogfile、true)); while(true){if(messagequeue.size()> 0){pw.println(messagequeue.poll()); } else {pw.flush(); thread.sleep(500); }}} catch(例外e){e.printstacktrace(); }最後に{if(pw!= null){pw.close(); }}}}}} / ** *指定されたクライアントリクエストを処理 * @Author Administrator * * / private Class clienthandlerを実装してrunnable {private socket socket; public clienthandler(socket socket){this.socket = socket; } public void run(){ / * * IDEA: *最初にクライアントから送信されたすべてのペアのログを受信します *「オーバー」まで *これらのペアのログをローカルファイルに保存し、クライアントに返信 *「OK」 *ステップを実行します。文字列は「オーバー」です。そうでない場合は、ペアのログであり、ローカルファイルに保存します。もしそうなら、 *読むのをやめなさい。 * 4:すべてのログを正常に読み取った後、クライアントに「OK」に返信 */ printwriter pw = null; try {// 1 pw = new Printwriter(new outputStreamWriter(socket.getOutputStream()、 "utf-8")); // 2 BufferedReader br = new BufferedReader(new inputStreamReader(socket.getInputStream()、 "utf-8")); // 3文字列メッセージ= null; while((message = br.readline())!= null){if( "over" .equals(message)){break; } // [メッセージ]を保存するためにログをファイルに書き込みます(message); } // 4 pw.println( "ok"); pw.flush(); } catch(Exception e){e.printstacktrace(); pw.println( "error"); pw.flush(); }最後に{try {//クライアントから切断して、リソースsocket.close(); } catch(ioexception e){e.printstacktrace(); }}}}}}}}}}}}}} 2。dmsclient.java
パッケージcom.dms; java.io.bufferedReader;インポートjava.io.file;インポートjava.io.io.ioexception; Import java.io.inputStreamReader; Import java.OutputStreamWriter; Import java.io.io.printwriter; Import java.io.io.randomacsfile; Import.net.socket; incoma.net.socket; java.util.hashmap; import java.util.list; import java.util.map; import java.util.map.entry; import java.util.set; Import org.dom4j.document; Import org.dom4j.element; Import org.dom4j.io.saxreader; com.dms.bo.logdataをインポート;インポートcom.dms.bo.logrec; /***このクライアントは、ユーザーにUNIXサービスを提供するサーバーで実行されます。 *サーバー上のユーザーの上流および下流の情報を読み取り、収集するために使用され、 *ペアリングしてソートアウトして、サマリーのためにサーバーに送信します。 * @author Administrator * */public class dmsclient {//属性定義//ステップ1:ログの必要なプロパティを解析// unixシステムログファイルプライベートファイルログファイル。 //解析されたログプライベートファイルTextLogFileのファイルを保存します。 // [ファイル]プライベートファイルLastPositionFileをブックマークします。 //各解析ログプライベートINTバッチのエントリ数。 //ステップ2:ログの属性をペアにします//ファイルプライベートファイルlogrecfileを保存します。 //ファイルプライベートファイルloginlogfileを保存します。 //ステップ3:ログの属性を解析する//アドレスprivate string serverhost; //サーバーポートPrivate int serverport; /***クライアントの初期化に使用されるコンストラクターメソッド* @throws例外*/public dmsclient()スロー例外{// 1構成ファイルconfig.xml map <string> config = loadconfig(); // piling System.out.println(config); // 2属性init(config)を初期化します。 } catch(Exception E){System.out.println( "初期化に失敗!"); eを投げる; }} / ** *コンストラクターメソッドの2番目のステップを初期化し、構成項目に従って属性を初期化 * @param config * @throws Exception * / private void init(map <string、string> config)throws {try {logfile = new file(config.get( "logfile")); textLogfile = new file(config.get( "textLogFile")); lastPositionFile = new file(config.get( "lastPositionFile")); batch = integer.parseint(config.get( "batch")); logrecfile = new file(config.get( "logrecfile")); loginlogfile = new file(config.get( "loginlogfile")); serverHost = config.get( "serverHost"); serverport = integer.parseint(config.get( "serverport")); } catch(Exception e){System.out.println( "初期化プロパティが失敗!"); e.printstacktrace(); eを投げる; }} / ** *コンストラクターメソッドの初期化の最初のステップは、構成ファイルを解析することです * @returnコンフィギュレーションファイルの各アイテムに返されたマップが保存されます。ここで、タグの中央の名前 * @throws例外 * /プライベートマップ<文字列> loadconfig( document doc = reader.read(new file( "config.xml"));要素root = doc.getRootelement(); map <string、string> config = new hashmap <string、string>(); /**すべてのサブタグを<config> tag*に取得し、各サブタグの名前をキーとして使用します。マップコレクションには*/ list <element> list = root.elements(); for(要素e:list){string key = e.getname();文字列値= e.getTextTrim(); config.put(key、value); } config; } catch(Exception e){System.out.println( "Parse Configurationファイル例外!"); e.printstacktrace(); eを投げる; }} / ***クライアントが動作を開始するためのメソッド*ループの3つのステップ:* 1:ログの解析* 2:ログのペア* 3:ログを送信* / public void start(){parselogs(); matchlogs(); sendlogs(); // while(true){// parse log // if(!parselogs()){// continue; //} // // log /// if(!matchlogs()){//失敗* / private boolean sendlogs(){ /**実装アイデア:* logrecfileファイルのすべてのペアリングされたログを読み取り、サーバーに接続して送信します。サーバーがすべてを受け取った場合*ファイルを削除できます。つまり、送信*が完了します。 *実装手順:* 1:Logrecfileファイルが存在する必要があります* 2:すべてのペアリングログをコレクションに読み取り、送信するのを待ちます* 3:ソケットを介してサーバーに接続* 4:すべてのペアのログをサーバーにシーケンスで送信します* 6:1つの文字列を1つの文字列に送信して、応答ストリームを送信する場合* 8:8:8:8:8:8:8:8: 「OK」、それはサーバーが正常であることを意味します *がすべてのログを受信し、その後、logrecfile *ファイルを削除して返すことができます送信は完了することを意味します。 * */ socket socket = null; try {// 1 if(!logrecfile.exists()){system.out.println(logrecfile+"not intable!"); falseを返します。 } // 2 list <string> matches = ioutil.loadLogrec(logrecfile); // 3 Socket = new Socket(serverHost、serverport); // 4 printwriter pw = new Printwriter(new outputStreamWriter(socket.getOutputStream()、 "utf-8")); // 5 for(string log:matches){pw.println(log); } // 6 pw.println( "over"); pw.flush(); // 7 BufferedReader br = new BufferedReader(new inputStreamReader(socket.getInputStream()、 "utf-8")); // 8文字列応答= br.readline(); // 9 if( "ok" .equals(response)){logrecfile.delete(); trueを返します。 } else {system.out.println( "log faild!"を送信! "); falseを返します。 }} catch(Exception e){System.out.println( "log failed!"を送信! "); e.printstacktrace(); }最後に{if(socket!= null){try {socket.close(); } catch(ioexception e){e.printstacktrace(); }} falseを返します。 } /***ステップ2:logをペアにします* @return true:ペアリングに正常に* false:ペアリングが失敗しました* /private boolean matchlogs(){ /**実装のアイデア:*最後のペアになったログインログで最初のステップで解析されたすべての新しいログを読み取りました*。 *タイプ8を見つけることができる限り、 *とペアにできるログインログを見つけることができます。 * *実装手順: * 1:必要な判断 * 1.1:logrecfileが存在するかどうか。存在する場合、上書きを避けるために、新しいペアリング作業が実行されなくなります。 * 1.2:TextLogFileファイルが存在する必要があります。 * 2:TextLogFileを読んで、ログを読み、 *コレクションを読みます。 (いくつかのlogDataインスタンス)* 3:LoginLogFileファイルが存在する場合、それは*前回に正常にペアになっていないログがあり、コレクションに合わせてペアリングされているコレクションに保存されます* 4:ペアリング作業* 4.1:コレクションを作成する* 4.2:2つのマップを節約して、2つのログを節約します* 4.3:3:3:Traの2つのログを節約します。ログインとログアウト * *キー:ユーザー、PID *値:logDataインスタンス * 4.4:ログアウトマップを通過し、各ログアウトログのキー *に従ってログインマップに対応するログインログを見つけ、ペア付きログのセットにペアリグログを保存します。ログインマップからペアのログ*にログインログを削除します。このようにして、**マップにログインしたときにペアリングが残っていないはずです。 * 5:ペアのログをlogrecfileに書き込む* 6:すべての対応のないログをログインログファイルに書き込む* 7:textlogfileファイルを削除* 8:ペアリングが完了したことを示します**/try {// 1 //1.1 if(logrecfile.exists()){return true; } //1.2 if(!textlogfile.exists()){system.out.println(textlogfile+"not incting!"); falseを返します。 } // 2 list <LogData>リスト= ioutil.loadlogdata(textlogfile); // 3 if(loginlogfile.exists()){list.addall(ioutil.loadlogdata(loginlogfile)); } // 4 //4.1リスト<Logrec> Matches = new ArrayList <Logrec>(); //4.2 Map <String、logData> loginmap = new Hashmap <String、logdata>(); map <string、logdata> logoutmap = new hashmap <string、logdata>(); //4.3 for(logdata logdata:list){string key = logdata.getuser()+ "、"+ logdata.getPid(); if(logdata.getType()== logdata.type_login){loginmap.put(key、logdata); } else if(logdata.getType()== logdata.type_logout){logoutmap.put(key、logdata); }} //4.4 set <entry <string、logdata >> entryset = logoutmap.entryset(); for(entry <string、logdata> e:entryset){logdata logout = e.getValue(); logdata login = loginmap.remove(e.getKey()); logrec logrec = new logrec(login、logout); matches.add(logrec); } // 5 ioutil.savecollection(matches、logrecfile); // 6 ioutil.savecollection(loginmap.values()、loginlogfile); // 7 textlogfile.delete(); // 8 trueを返します。 } catch(Exception e){System.out.println( "ペアリングログに失敗!"); e.printstacktrace(); } falseを返します。 } /** * Step 1: parse the log* @return true: parse successful* false: parse failed*/ private boolean parseLogs(){ /* * Implementation idea: * Loop reading batch logs, then parse * 5 information in each log, and finally form a string, write it to the textLogFile file in * behavior units* * Implementation steps: * 1: Necessary judgment work* 1.1: In order to avoid the parsed log not being usedしかし、 *最初のステップにより実行が繰り返され、前のログが上書きされます *、ここで判断する必要があります。解析されたログ*を保存すると、ログファイルが存在し、最初のステップは実行されなくなります。 *このログファイルは、2番目のステップがペアリングされた後に削除されます。 * 1.2:logfileファイルが存在する必要があります(wtmpxファイル) * 1.3:解析できるログはまだありますか * 2:logfileを読み取るためにランダムアッケスファイルを作成します * 3:ポインターを最後の読み取り位置に移動します *新しい解析作業 * 4:4.4:4.1:lop battaing in save on lop data inscaged dighted(4.1:4.1:各ログ(ユーザー、PID、タイプ、時間、ホスト) *の5つの内容 *およびlogDataインスタンスで保存してから、 * logDataインスタンスをコレクションに保存 * 5:動作単位のすべてのログを * textlogfile * 6:ブックマーク情報を保存 * 7:ワークが完了したことを示します。 try {// 1 //1.1 if(textlogfile.exists()){return true; } //1.2 if(!logfile.exists()){system.out.println(logfile+"not inced!"); falseを返します。 } //1.3 long lastposition = haslogs(); // piling // system.out.println(// "lastposition:"+lastposition //); if(lastposition <0){system.out.println( "ログは解析できない!"); falseを返します。 } // 2 raf = new RandomAccessFile(logfile、 "r"); // 3 raf.seek(lastposition); // 4 list <LogData>リスト= new ArrayList <LogData>(); for(int i = 0; i <batch; i ++){//各解析の前に、(logfile.length() - lastposition <logdata.log_length){break; } // parse user raf.seek(lastposition+logdata.user_offset); string user = ioutil.readstring(raf、logdata.user_length).trim(); // parse pid raf.seek(lastposition+logdata.pid_offset); int pid = raf.readint(); // Parse Type Raf.seek(lastPosition+logdata.type_offset); short type = raf.readshort(); // parse time raf.seek(lastposition+logdata.time_offset); int time = raf.readint(); //ホストraf.seek(lastposition+logdata.host_offset); string host = ioutil.readstring(raf、logdata.host_length).trim(); logData log = new logData(ユーザー、PID、タイプ、時間、ホスト); list.add(log); // piling // system.out.println(log); // logをアップロードする、lastposition lastposition = raf.getfilepointer()を更新します。 } // 5 ioutil.savecollection(list、textlogfile); // 6ブックマークファイルを保存ioutil.savelong(lastposition、lastpositionFile); // 7 trueを返します。 } catch(Exception e){System.out.println( "ログが失敗する!"); e.printstacktrace(); }最後に{if(raf!= null){try {raf.close(); } catch(ioexception e){e.printstacktrace(); }} falseを返します。 } /***最初のステップは、ログ内のリンクを解析することです。 *ブックマークファイルのレコードの場所によると、解析するためのログがまだあるかどうかを判断します。ある場合、最後の位置*が返されます。ない場合は、-1を返します。 * @return */ private long haslogs(){try {/ * * lastpositionFileが存在しない場合、それは *ゼロから解析されたことがないことを意味します。 } long lastposition = ioutil.readlong(lastPositionFile); if(logfile.length() - lastposition> = logdata.log_length){return lastposition; }} catch(例外e){e.printstacktrace(); } return -1; } public static void main(string [] args){try {dmsclient client = new dmsclient(); client.start(); } catch(Exception e){System.out.println( "クライアントRun Failed!"); }}} 3。ioutil.java
パッケージcom.dms; java.io.bufferedreader; Import java.io.file; import java.io.fileinputStream; Import java.io.inputStreamReader; Import java.io.printwriter; Import java.io.io.randomacessfile; com.dms.bo.logdata; /** *このクラスは、クライアントIO操作を担当するツールクラス * @Author Administrator * * try {br = new BufferedReader(new inputStreamReader(new FileInputStream(file))); List <String> list = new ArrayList <String>();文字列line = null; while((line = br.readline())!= null){list.add(line); }返品リスト。 } catch(Exception e){e.printstacktrace(); eを投げる; }最後に{if(br!= null){br.close(); }}} /** *指定されたファイルから各ペアリグログを読み取り、コレクションに保存してから返します。 * @param file * @return * @throws Exception */ public static list <logdata> loadlogdata(file file)throws exception {bufferedreader br = null; try {br = new BufferedReader(new inputStreamReader(new FileInputStream(file))); List <LogData> list = new ArrayList <LogData>();文字列line = null; while((line = br.readline())!= null){logdata logdata = new logdata(line); list.add(logdata); }返品リスト。 } catch(Exception e){e.printstacktrace(); eを投げる; }最後に{if(br!= null){br.close(); }}} / ** *指定された長い値を指定されたファイルの最初の行に文字列として書き込む * @param l * @param file * @throws例外 * / public static void savelong(long lon、file file)throws exception {printwriter pw = null; try {pw = new Printwriter(file); pw.println(lon); } catch(Exception e){e.printstacktrace(); eを投げる; }最後に{if(pw!= null){pw.close(); }}}}} /***コレクション内の各要素のtoStringメソッドによって返された文字列を書き込み、動作ユニットの指定されたファイルに書き込みます。 * @param c * @param file * @throws例外 */ public static void savecollection(collection c、file file)throws exception {printwriter pw = null; try {pw = new Printwriter(file); for(オブジェクトO:c){pw.println(o); }} catch(例外e){e.printstacktrace(); eを投げる; }最後に{if(pw!= null){pw.close(); }}} / ** *指定されたランダムアッケスファイルの現在の位置から連続して開始します *長さのバイトを読み取り、戻り、return * @param raf * @param length * @return * / public static string readString(randomaccessfile raf、int length)throws throws Exception raf.read(data);新しい文字列(データ、 "ISO8859-1")を返します。 } catch(Exception e){e.printstacktrace(); eを投げる; }} / ** *指定されたファイルから文字列の最初の行を読み取り、 * return * @return * @throws例外 * / public static longlong(file file)throws exception {bufferedreader br = null; try {br = new BufferedReader(new inputStreamReader(new FileInputStream(file))); string line = br.readline(); long.parselong(line); } catch(Exception e){e.printstacktrace(); eを投げる; }最後に{if(br!= null){br.close(); }}}}
4。config.xml
<?xml version = "1.0" encoding = "utf-8"?> <config> <! - unixシステムログファイル名 - > <logfile> wtmpx </logfile> <! - 解決されたログファイル名を保存 - > <> <textlogfile> log.txt </textlogfile> <解析されたログごとのエントリ数 - > <batch> 10 </batch> <! - ペアのログファイル名 - > <logrecfile> logrecfile </logrecfile> <! - nobled logファイル名 - > <loginlogfile> loign.txt </loginlogfile> <! <! - サーバーアドレス - > <serverhost> localhost </serverhost> <! - serverポート - > <serverport> 8088 </serverport> </config>
5。ServerConfig.xml
<?xml version = "1.0" encoding = "utf-8"?> <config> <! - ペアのログファイルを保存するサーバーのファイル名 - > <logrecfile> server-logs.txt </logrecfile> <!
上記はこの記事に関するものです。すべての人の学習に役立つことを願っています。