<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Terry.Li-彬

    虛其心,可解天下之問(wèn);專其心,可治天下之學(xué);靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      143 隨筆 :: 344 文章 :: 130 評(píng)論 :: 0 Trackbacks
    使用定制的 Web Service Appender for Log4j 將日志信息發(fā)送到某一集中位置。Log4j Appender 使您可以在面向服務(wù)架構(gòu) (SOA) 解決方案中調(diào)試和跟蹤任意問(wèn)題。

    引言

    你 可以使用 Web Service Appender 將日志集中到某一位置,同時(shí),Web Service Appender 允許管理者監(jiān)控、開發(fā)者調(diào)試面向服務(wù)架構(gòu)(SOA)環(huán)境里可能存在的任何問(wèn)題。Web Service Appender 是一種擴(kuò)展 JAVA 類,它由 Log4j 的 Appender 類擴(kuò)展而來(lái)。

    從定義上看,SOA 是一種彼此可以互相通信的服務(wù)集合,但這些服務(wù)的內(nèi)容是各自獨(dú)立的,每一類服務(wù)均不受其它服務(wù)內(nèi)容或服務(wù)狀態(tài)的影響,并且這些服務(wù)都工作在分布式的系統(tǒng)架 構(gòu)里。在 SOA 中,Web 服務(wù)通常被用來(lái)在給定事務(wù)中處理請(qǐng)求,這些請(qǐng)求可以是遺留代碼、企業(yè)級(jí) Java Beans(EJBs) 的封裝,也可以是 Java 類的封裝,使用一種可以將日志信息聚集在中心位置里的日志紀(jì)錄方法,能幫助您隔離缺陷和問(wèn)題,并能讓你更好的理解邏輯流的處理。

    將特定模塊或服務(wù)的日志消息紀(jì)錄到一個(gè)中心位置的機(jī)制,可以把可能潛在的問(wèn)題和缺陷降低到最小。

    本文對(duì) Log4j 的功能進(jìn)行了大體的概述,并介紹了如何編寫自定義的 Log4j Appender,這類特殊的 Appender 將日志消息編到一種特定的 Web 服務(wù)。





    回頁(yè)首


    Log4j 快速入門

    Log4j 是一種開放源代碼的日志庫(kù),它已被發(fā)展為 Apache Software Foundation 日志服務(wù)項(xiàng)目的子項(xiàng)目。該庫(kù)是以 IBM 在 90 年代末開發(fā)的日志庫(kù)為基礎(chǔ)的,第一版發(fā)布于 1999 年。現(xiàn)在它在開放源代碼團(tuán)體得到了廣泛使用,它的體系是圍繞以下三個(gè)主要概念構(gòu)建起來(lái)的:

    • Logger
    • Appender
    • Layout

    這些概念可以讓您根據(jù)消息類型、消息優(yōu)先級(jí)來(lái)紀(jì)錄消息,您可以控制消息在何處結(jié)束及消息如何格式化。 Logger 是應(yīng)用程序首先調(diào)用以初始化消息紀(jì)錄的對(duì)象。當(dāng)把某一消息傳遞給日志時(shí),logger 會(huì)生成 LoggingEvent,對(duì)消息進(jìn)行封裝。之后,Logger 對(duì)象將 LoggingEvent 傳遞給與之關(guān)聯(lián)的 Appender。

    Appender 將 LoggingEvent 所包含的消息發(fā)送給指定的目標(biāo)輸出文件。所謂指定的文件,大多數(shù)情況下,是 Log4 屬性文件。一些 Appender 存在于 Log4j 中。您也可以擴(kuò)展 Appender,使之支持其它的目標(biāo)文件,比如 XML 文件、控制臺(tái)等等。

    在 Log4j 里, LoggingEvent 被賦予某一級(jí)別,以表明它們的優(yōu)先級(jí)。缺省的級(jí)別包括如下幾種:

    • OFF:可能是最高的級(jí)別,它是用來(lái)關(guān)閉日志紀(jì)錄的
    • FATAL:指出現(xiàn)了非常嚴(yán)重的錯(cuò)誤事件,這些錯(cuò)誤可能會(huì)導(dǎo)致應(yīng)用程序異常中止
    • ERROR:指雖有錯(cuò)誤,但仍允許應(yīng)用程序繼續(xù)運(yùn)行
    • WARN:指運(yùn)行環(huán)境潛藏著危害
    • INFO:指報(bào)告信息,這些信息在粗粒度級(jí)別上突出顯示應(yīng)用程序的進(jìn)程
    • DEBUG:指細(xì)粒度信息事件,細(xì)粒度信息事件對(duì)于應(yīng)用程序的調(diào)試是最有用的
    • ALL:可能是最低的級(jí)別,其目的是打開所有日志記錄
    Logger 和 Appender 也被賦予上述的某一級(jí)別,并且僅執(zhí)行等于或高于它們自身的級(jí)別的日志請(qǐng)求。比如,如果一個(gè) Appender 屬于 INFO 級(jí)別,而日志請(qǐng)求屬于 DEBUG,那么 Appender 將不會(huì)為給定的日志事件寫消息。



    回頁(yè)首


    客戶端組件

    客戶端 log4j.properties 文件

    客戶端 log4j.properties 文件是一種標(biāo)準(zhǔn)文件,它包含服務(wù)或模塊使用的所有 Appender。Web Service Appender 要求有一個(gè)端點(diǎn)(endpoint) 屬性以指定所使用的日志服務(wù)。

    清單 1 描述了使用 WebServiceAppender 所必需的 Web 服務(wù)客戶端 Log4j 屬性。 黑體顯示的文本指明了將訪問(wèn) WebServiceAppender 服務(wù)器端的 Appender。屬性文件是使用 Log4j 的基本需求,它可以讓您配置應(yīng)用程序以使用多個(gè) Appender 以及 logging severity。一旦應(yīng)用程序進(jìn)入運(yùn)行狀態(tài)或潛在的問(wèn)題得到解決,您就可以輕松地修改屬性文件。


    清單 1:客戶端 Log4j 的屬性文件

    #set the level of the root logger
    log4j.rootLogger = INFO, CONSOLE
    #set own logger
    log4j.logger.com.carmelouria.logging.test=CONSOLE
    log4j.appender.CONSOLE=com.carmelouria.logging.WebServiceAppender
    log4j.appender.CONSOLE.endpoint=
    http://localhost:9080/log4j/services/LogAppenderService

    log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n





    回頁(yè)首


    服務(wù)器的 Log4j.properties 文件

    服 務(wù)器 Log4j.properties 文件被用來(lái)關(guān)聯(lián)客戶端 Log4j 屬性文件,它指定了日志的級(jí)別及服務(wù)器將如何輸出消息。對(duì)于支持 Log4j 的應(yīng)用程序,您可以定義多個(gè) appender。當(dāng)然,這些 appender 既可以用于客戶端服務(wù),也可以用于服務(wù)模塊。

    清單 2 描述了一份典型的 Log4j 屬性文件,服務(wù)器端的 WebServiceAppender 使用缺省的 Log4j Appenders。服務(wù)器端的 Appender 可以潛在的調(diào)用另一個(gè) WebServiceAppender,并將日志信息鏈接起來(lái):


    清單 2:服務(wù)器端的 Log4j 屬性文件

    #set the level of the root logger
    log4j.rootLogger = INFO, FILE
    #set own logger
    log4j.appender.FILE=org.apache.log4j.RollingFileAppender
    log4j.appender.FILE.file=c:/temp/log4j/server/server.log
    log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.FILE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n

    客戶端程序測(cè)試示例:

    這個(gè)客戶端程序示例是無(wú)格式普通 Java 對(duì)象(POJO),它記錄了一條消息,并被配置為使用 Web Service Appender 來(lái)處理消息。清單 3 顯示了這個(gè)示例:


    清單 3:客戶端應(yīng)用程序使用 WebServiceAppender 的示例

    package com.carmelouria.logging.test;
    import org.apache.log4j.Level;
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    /**
    * @author Carmelo Uria
    *
    */
    public class LoggingSample
    {
    private static Logger logger = Logger.getLogger(LoggingSample.class.getName());
    /**
    *
    */
    public LoggingSample()
    {
    super();
    PropertyConfigurator.configure("c:/temp/log4j.properties");
    logger.log(Level.INFO, "LoggingSample instantiation...");
    System.out.println("finished...");
    }
    public static void main(String[] args)
    {
    LoggingSample sample = new LoggingSample();
    }
    }





    回頁(yè)首


    WebServiceAppender

    WebServiceAppender 是必需的,它可以將消息發(fā)送到指定的 Web 服務(wù)。WebServiceAppender 繼承了 org.log4j.Appender,它允許使用 log4.properties,并成為有效的 Log4j Appender。

    WebServiceAppender 使用基于 XML 的遠(yuǎn)程過(guò)程調(diào)用 (JAX-RPC) 的 Java API,來(lái)將消息發(fā)送到服務(wù)器。JAX-RPC 是一種規(guī)范,它描述使用 RPC 和 XML 構(gòu)建 Web 服務(wù)和 Web 服務(wù)客戶端的應(yīng)用編程接口 (API) 和約定。JAX-RPC 又被稱為 JSR 101。

    LoggingEvent 通過(guò) SOAPElement 被分割并表示為 XML。javax.xml.soap.SOAPElement 接口意味著服務(wù)端點(diǎn)接口將包含一個(gè)參數(shù),或返回 javax.xml.soap.SOAPElement 類型的值,以對(duì)應(yīng)于 schema 中每個(gè)使用<xsd:any/>的地方。從本質(zhì)上看,它是 XML 參數(shù)的封裝,且沒有相應(yīng)的序列化/反序列化 JAVA 類。例如,一旦客戶請(qǐng)求記錄一個(gè)消息,就會(huì)創(chuàng)建一個(gè) LoggEvent 對(duì)象,然后傳送給 Appender。在這種情況下,Appender 就是 WebServiceAppender。Appender 檢索事件,并在解析事件中的信息。一些額外的信息會(huì)被加入,如主機(jī)名稱,這樣您就知道這些消息來(lái)自哪個(gè)系統(tǒng)。同時(shí),append 方法也將消息轉(zhuǎn)換為 SOAPElement,這樣就可以通過(guò) executeWebService 方法將消息傳遞給 Web 服務(wù)。使用 SOAPElement 充分考慮了 WebServiceAppender 未來(lái)版本的可擴(kuò)展性問(wèn)題。


    清單4:執(zhí)行 WebServiceAppender 服務(wù)的 Append 方法

    protected void append(LoggingEvent event)
    {
    // create Web Service client using endpoint
    if (endpoint == null)
    {
    System.out.println("no endpoint set. Check configuration file");
    System.out.println("[" + hostname + "] " + this.layout.format(event));
    return;
    }
    executeWebService(event);
    }
    private void executeWebService(LoggingEvent event)
    {
    SoapClient client = new SoapClient();
    URL endPoint = null;
    try
    {
    endPoint = new URL(getendpoint());
    }
    catch (MalformedURLException e1)
    {
    e1.printStackTrace();
    }
    String nameSpace = "http://ejb.logging.carmelouria.com";
    QName serviceName = new QName(nameSpace, "LogAppenderServiceService");
    QName operation = new QName(nameSpace, "log");
    QName port = new QName(nameSpace, "LogAppenderService");
    Parameter message =
    new Parameter("log", Constants.XSD_ANY, SOAPElement.class, ParameterMode.IN);
    try
    {
    /**
    *create SOAPElement from LoggingEvent need hostname
    */
    Level level = event.getLevel();
    String sysLog = "<syslog>" + new Integer(level.getSyslogEquivalent()).toString()
    + "</syslog>";
    String startTime = new Long(LoggingEvent.getStartTime()).toString();
    String timeTag = "<start_time>" + startTime + "</start_time>";
    String hostName = "<hostname>" + InetAddress.getLocalHost() +
    "</hostname>";
    String threadName = "<thread_name>" + event.getThreadName()
    +"</thread_name>";
    String logger = "<logger>" + event.getLoggerName() + "</logger>";
    String eventMessage = "<message>" + event.getRenderedMessage() +
    "</message>";
    String log = hostName + threadName + logger + timeTag + sysLog +
    eventMessage;
    String throwableInformation[] = event.getThrowableStrRep();
    if (throwableInformation != null)
    {
    for (int i = 0; i < throwableInformation.length; i++)
    {
    String throwable = "<throwable_information>" + throwableInformation[i] +
    "</throwable_information>";
    log += throwable;
    }
    }
    String ndcString = event.getNDC();
    if (throwableInformation != null)
    {
    String throwable = <ndc>" + ndcString + </ndc>";
    log += throwable;
    }
    message.setValue(SOAPElementFactory.create(<log>" + log + </log>"));
    }
    catch (UnknownHostException unknownHostException)
    {
    unknownHostException.printStackTrace();
    }
    catch (SOAPException e2)
    {
    e2.printStackTrace();
    }
    Parameter resultType = newParameter("logResponse",
    Constants.WEBSERVICES_VOID,
    Object.class,
    ParameterMode.OUT);
    Parameter[] parameters = { message };
    try
    {
    // execute client
    Object result =
    client.execute(endPoint, serviceName, operation, "wrapped", null,
    port, resultType, parameters);
    if ((result != null) && (result instanceof String))
    System.out.println((String) result);
    }
    catch (ClientException e)
    {
    e.printStackTrace();
    }
    }

    Hostname

    不幸的是,Log4j 的 LoggingEvent 沒有包含 Hostname,而 Hostname 是 Web Service Appender 眾多需求之一。在創(chuàng)建 SOAPElement 以前,您可以用下面的語(yǔ)句將 Hostname 添加到 XML 文件里:

    String hostName = "<hostname>" + InetAddress.getLocalHost() + "</hostname>";

    SoapElementFactory

    SoapElementFactory 是主要用于創(chuàng)建 SOAPElement 的類。它同時(shí)支持創(chuàng)建 IBM 和 Java 的 SOAPElement 實(shí)現(xiàn),如清單 5 所示:


    清單 5:使用 SoapElementFactory 類的創(chuàng)建方法

    public static javax.xml.soap.SOAPElement create(String xml) throws SOAPException
    {
    com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory factory =
    (com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory)
    com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory
    .newInstance();
    SOAPElement element =
    (javax.xml.soap.SOAPElement)factory.createElementFromXMLString(xml);
    return(element);
    }
    public static SOAPElement create(String arg0, String arg1, String arg2,
    boolean ibmSoapElement) throws
    SOAPException
    {
    if (ibmSoapElement)
    {
    SOAPFactory soapFactory =
    (com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory)
    com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory.newInstance();
    return (soapFactory.createSOAPElement(arg0, arg1));
    }
    javax.xml.soap.SOAPFactory soapFactory =
    javax.xml.soap.SOAPFactory.newInstance();
    return (soapFactory.createElement(arg0, arg1, arg2));
    }

    SoapClient

    SoapClient 類封裝了 Call 接口的 JAX-RPC 實(shí)現(xiàn),javax.xml.rpc.Call 接口提供了對(duì)服務(wù)端點(diǎn)動(dòng)態(tài)調(diào)用的支持。javax.xml.rpc.Service 接口就好象是創(chuàng)建 Call 實(shí)例的工廠。

    清單 6 說(shuō)明了客戶端如何動(dòng)態(tài)調(diào)用服務(wù)。這允許對(duì)服務(wù)進(jìn)行變更,而無(wú)需生成客戶端代理來(lái)訪問(wèn)遠(yuǎn)程服務(wù)。


    清單 6:使用 SoapClient 類的調(diào)用方法

    private Object call(SoapService service, QName operation, QName portType,
    String operationStyleProperty,
    String encodingURIProperty, Parameter returnType,
    Parameter[] parameters) throws ClientException
    {
    QName portName;
    String response = null;
    Object results = null;
    Call call = null;
    try
    {
    // check to see if Service object exists
    if (service == null)
    throw new ClientException("Invalid Service object. It maybe null.");
    // retrieve call from Service object
    call = service.createCall();
    call.setOperationName(operation);
    call.setPortTypeName(portType);
    // check call object
    if (call == null)
    throw new ClientException("invalid operation. Call object is null.");
    // set default values
    if (operationStyleProperty == null)
    call.setProperty(Call.OPERATION_STYLE_PROPERTY,
    OPERATION_STYLE_DOCUMENT_TYPE);
    else
    call.setProperty(Call.OPERATION_STYLE_PROPERTY,
    operationStyleProperty);
    if (encodingURIProperty == null)
    call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY,
    ENCODING_LITERAL);
    else
    call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY,
    encodingURIProperty);
    call.setTargetEndpointAddress(service.getServiceEndPoint());
    //create Parameter class for SoapClient
    for (int i = 0; i < parameters.length; i++)
    {
    Class classObject = parameters[i].getClassObject();
    if (classObject != null)
    call.addParameter(parameters[i].getName(), parameters[i].getXmlType(),
    parameters[i].getClassObject(), parameters[i].getMode());
    else
    call.addParameter(parameters[i].getName(), parameters[i].getXmlType(),
    parameters[i].getMode());
    }
    // pass parameter as ReturnType
    if (returnType != null)
    {
    if (returnType.getClassObject() != null)
    call.setReturnType(returnType.getXmlType(), returnType.getClassObject());
    else
    call.setReturnType(returnType.getXmlType());
    }
    Object[] request = new Object[parameters.length];
    // add parameter values
    for (int i = 0; i < request.length; i++)
    {
    request[i] = parameters[i].getValue();
    }
    results = call.invoke(request);
    }
    catch (SOAPFaultException e)
    {
    System.out.println(e.getFaultString());
    e.getStackTrace();
    throw new ClientException(e.getLocalizedMessage(), e);
    }
    catch (ServiceException serviceException)
    {
    serviceException.getStackTrace();
    throw new ClientException(serviceException.getLocalizedMessage(),
    serviceException);
    }
    catch (RemoteException exception)
    {
    exception.printStackTrace();
    throw new ClientException(exception.getLocalizedMessage(), exception);
    }
    return (results); }





    回頁(yè)首


    服務(wù)組件

    Log4j.server.properties

    Log4j.server.properties 文件包含了一個(gè)基本的 Log4j 配置文件,該文件可以讓您指定把哪些日志發(fā)送給 Web 服務(wù)系統(tǒng)。


    清單 7:Log4j.server.properties 文件

    #set the level of the root logger
    log4j.rootLogger = INFO, FILE
    #set own logger
    log4j.appender.FILE=org.apache.log4j.RollingFileAppender
    log4j.appender.FILE.file=c:/temp/log4j/server/server.log
    log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.FILE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n

    LogAppenderBean.java

    LogAppenderBean.java 是 Web Service Appender 服務(wù)所要使用的 EJB。該服務(wù)啟動(dòng) LogAppenderBean 以處理來(lái)自每個(gè) Web Service Appender 客戶端的每一個(gè)請(qǐng)求。

    清單 8 顯示了來(lái)自 WebServiceAppender EJB 的 log 方法,該方法解析來(lái)自客戶端的消息,并將客戶端信息紀(jì)錄到服務(wù)的服務(wù)器端。


    清單 8:LogAppenderBean 的 log 方法

    public void log(SOAPElement message)
    {
    try
    {
    InputSource source = ((IBMSOAPElement)
    message).toInputSource(false);
    Document document = Parser.parse(source);
    String log = null;
    String hostname =
    document.selectSingleNode("http://hostname").getText();
    String threadName =
    document.selectSingleNode("http://thread_name").getText();
    String syslog =
    document.selectSingleNode("http://syslog").getText();
    String startTime = new Long(
    document.selectSingleNode("http://start_time").
    getText()).toString();
    log = '[' + startTime + ':' + hostname + ':' + threadName +
    "] " + document.selectSingleNode(
    "http://message").getText();
    // retrieve any throwable messages
    List throwableList = document.selectNodes(
    "http://throwable_information");
    if(throwableList != null)
    {
    Iterator throwables = throwableList.iterator();
    while(throwables.hasNext())
    {
    log += '\n' + ((Node)throwables.next()).getText();
    }

    log += '\n';
    }

    logger.log(Level.toLevel(new Integer(syslog).intValue()),
    log);
    logger.log(Level.INFO,log);
    }
    catch(ParserException parseException)
    {
    parseException.printStackTrace();
    }
    catch (SAXException e)
    {
    e.printStackTrace();
    }
    }

    通過(guò) IBM SOAPElement 的 InputSource,每一個(gè) SOAPElement 的內(nèi)容都會(huì)被檢索。目前,只有 IBM WebSphere? Application Server (Application Server) 支持這些代碼(請(qǐng)參閱參考資料)。 然而,如果您移除 IBM SOAPElement,那么您就可以在任何應(yīng)用服務(wù)器上使用這些代碼。IBM SOAPElement 內(nèi)置的性能優(yōu)化也適用于 Application Server。

    每一個(gè) SOAPElement 都使用 Dom4j 來(lái)讀取、解析和轉(zhuǎn)換。Dom4j 是一種在內(nèi)存中表示 XML 樹的對(duì)象模型。Dom4j 提供了一組易于使用的 API,從而為我們提供了一整套強(qiáng)大的功能來(lái)處理、操作或定位 XML,使用 XPath 和 XSLT 進(jìn)行工作,以及與 SAX、 JAXP、DOM 集成。

    除了可以使用任意的 XML 解析器外,DOM4J 還允許使用任意的 SAX 解析器,為實(shí)現(xiàn)更好的性能,還允許使用所有標(biāo)準(zhǔn)的 XSLT 轉(zhuǎn)換器。 轉(zhuǎn)換被用來(lái)析取發(fā)送給 Web Service Appender 的客戶端 LoggingEvent 的元素。

    如果您允許使用 SOAPElement,那么就需要在代碼中維持最大限度的靈活性。Web Service Appender 服務(wù)可以被修改,以支持所有發(fā)送給服務(wù)的 XML。





    回頁(yè)首


    輸出

    下面的示例展示了 Web Service Appender 的可能的輸出:

    INFO [WebContainer : 0] ejb.LogAppenderBean (log:?) :: [1111513482641:OO7-64BIT/9.48.114.183:main]LoggingSample instantiation...

    OO7-64BIT/9.48.114.183 是機(jī)器名和 IP 地址,而 main 是日志所在處的方法名。





    回頁(yè)首


    結(jié)束語(yǔ)

    Web Service Appender 是將日志集中到某一位置的基本工具。由于 Web Service Appender 是 Log4j 的 Appender 類的子集,因而配置和使用 Appender 都非常簡(jiǎn)單易懂。您可以修改 Log4j 的屬性文件,這樣,使用 Log4j 的現(xiàn)有應(yīng)用程序和服務(wù)就可以馬上使用 Web Service Appender。






    回頁(yè)首


    下載

    描述名字大小下載方法
    Foundation Class Libraryfoundation.zip47 KBHTTP
    Logging Web Service J2EE ApplicationLoggingWebService.ear1976 KBHTTP
    Unit Test Sample CodeSoapClientTest.java5 KBHTTP
    posted on 2009-07-15 11:49 禮物 閱讀(702) 評(píng)論(0)  編輯  收藏 所屬分類: web serviceLog
    主站蜘蛛池模板: 一级毛片**免费看试看20分钟| 国产亚洲中文日本不卡二区| 国产午夜亚洲精品不卡免下载| 在线观看免费视频资源| 99久久99久久精品免费看蜜桃| 久久精品国产亚洲av日韩| 免费A级毛片无码A∨| 亚洲视频免费一区| 91黑丝国产线观看免费 | 国产成人自产拍免费视频| 亚洲Av无码乱码在线观看性色| 亚洲精品动漫免费二区| 成人免费视频国产| 人成免费在线视频| 亚洲精品中文字幕无码蜜桃| 无码AV片在线观看免费| 亚洲国产成人手机在线电影bd| 我要看免费的毛片| 一级看片免费视频| 久久精品亚洲综合| 免费H网站在线观看的| 亚洲hairy多毛pics大全| 亚洲国产成人精品无码久久久久久综合| 国产精品福利片免费看| 亚洲综合一区二区国产精品| 成人毛片手机版免费看| 一级毛片a免费播放王色| 亚洲男人第一av网站| 毛片a级毛片免费观看免下载| 农村寡妇一级毛片免费看视频| 亚洲色成人中文字幕网站| 8x成人永久免费视频| 亚洲成a人无码亚洲成av无码| 国产亚洲一区区二区在线| 99re免费在线视频| 婷婷国产偷v国产偷v亚洲| 亚洲s色大片在线观看| 国内自产少妇自拍区免费| 十八禁视频在线观看免费无码无遮挡骂过 | a级毛片在线免费| 日本亚洲色大成网站www久久 |